C &

3 Cevap php

Ben bit operatörleri ile aşina değilim, ama onları daha önce basit ayarları saklamak için kullanılan görünüyorlar.

Ben bir işleve / off seçenekleri birkaç geçmesi gerekiyor, ve ben bunun için bir tek tamsayı kullanmak istiyorum. Nasıl ayar ve bu seçenekleri okuma hakkında gidebilir?

3 Cevap

Emin PHP bunu yapabilirsiniz.

Diyelim ki tek bir değer saklamak istediğiniz dört booleans var diyelim. Bu nedenle depolama alanı dört biti gerekiyor demektir

0000

Her bit, tek tek ayarladığınızda, ondalık benzersiz bir temsil var

0001 = 1 // or 2^0
0010 = 2 // or 2^1
0100 = 4 // or 2^2
1000 = 8 // or 2^3

Bunu uygulamak için ortak bir yol, her seçeneği temsil etmek bit maskeleri ile. PHP'nin hata seviyeleri, örneğin, bu şekilde yapılır.

define( 'OPT_1', 1 );
define( 'OPT_2', 2 );
define( 'OPT_3', 4 );
define( 'OPT_4', 8 );

Bu bayrakların 0 veya daha fazla temsil eden bir tamsayı olduğunda Sonra, & olduğu bitsel ve operatörü ile kontrol

$options = bindec( '0101' );
// can also be set like this
// $options = OPT_1 | OPT_3;

if ( $options & OPT_3 )
{
  // option 3 is enabled
}

Bu operatör gibi çalışır: her iki işlenen ayarlanır sadece bit sonucu ayarlanır

0101 // our options
0100 // the value of OPT_3
----
0100 // The decimal integer 4 evaluates as "true" in an expression

Biz OPT_2 karşı kontrol eğer, o zaman sonuç böyle olmazdı

0101 // our options
0010 // the value of OPT_2
----
0000 // The decimal integer 0 evaluates as "false" in an expression

Bu hemen hemen her iki dilde de aynı şekilde çalışır, yan kıyasla bir yan:

C:

#include <stdio.h>
#include <stdint.h>

#define FLAG_ONE 0x0001
#define FLAG_TWO 0x0002
#define FLAG_THREE 0x0004
#define FLAG_FOUR 0x0008
#define FLAG_ALL (FLAG_ONE|FLAG_TWO|FLAG_THREE|FLAG_FOUR)

void make_waffles(void)
{
   printf("Yummy! We Love Waffles!!!\n");
}

void do_something(uint32_t flags)
{
    if (flags & FLAG_TWO)
         make_waffles();
}

int main(void)
{
    uint32_t flags;

    flags |= FLAG_ALL;

    /* Lets make some waffles! */
    do_something(flags);

    return 0;
}

PHP:

<?php

define("FLAG_ONE", 0x0001);
define("FLAG_TWO", 0x0002);
define("FLAG_THREE", 0x0004);
define("FLAG_FOUR", 0x0008);
define("FLAG_ALL", FLAG_ONE|FLAG_TWO|FLAG_THREE|FLAG_FOUR);

function make_waffles()
{
    echo 'Yummy! We Love Waffles!!!';
}

function do_something($flags)
{
    if ($flags & FLAG_TWO)
       make_waffles();
}

$flags |= FLAG_TWO;
do_something($flags);

?>

Not, kesinlikle ben sadece alışkanlık onları kullanmak, sabitler kullanmak gerekmez. Her iki örnek de ben gcc -Wall flags.c -o flags aracılığıyla C sürümü derlenmiş, çalışacaktır. Değişim flags bir şey ama FLAG_TWO veya FLAG_ALL örneğin ve (ne yazık ki) ya da hiçbir waffle yapılacaktır.

C sürümünde, don't Önişlemci gıdıklamak için var, bu oldukça kolay, vb, bir enum olabilir - o okuyucu için bir egzersiz var.

quote "the idea is not good, really. you would better pass few boolean. if you want use bitwise then

function someFunc($options)
{

   if ($options & 1 != 0)
      //then option 1 enabled
   if ($options & (1 << 1) != 0)
      //then option 2 enabled      
   if ($options & (1 << 2) != 0)
      //then option 3 enabled      
}

"

Eğer tek bir değer için kontrol olsaydı ne yaptın tam biz aşağıdaki yöntemleri olabilir uygun olmasa da, bu yüzden biraz etkin olduğunu kontrol, ama biz herhangi bir ya da maç mümkün istedim Diyelim, iyi olurdu

function matchExact($in, $match) { // meets your criterion, as would a switch, case, but ultimately not suited for use with flags
    return $in === $match;
}

function matchAny($in, $match) { // meets original criterion with more lexical name however it returns true if any of the flags are true
    return $in |= $match;
}

Eğer sadece oluyor belirli eylemler sahip bu üzerine genişletmek istiyorsa bit x, y, z etkinse o zaman aşağıdaki kullanabilirsiniz

function matchHas($in, $match) { // more bitwise than === as allows you to conditionally branch upon specific bits being set
    return $in &= $match;
}

Eğer yukarıdaki alıntıda yapıldı ne yapıyorsun ben de düşünüyorum, bayraklar iyi bir fikir olmayabilir, kesin değerler daha sağduyulu eylemleri izin parası var ki, daha iyi olabilir. (0-255) 8-bit üzerinde 8 ayrı bayrakları için

2 tabanı "8" "4" içermiyor, ve "2", "1" içermiyor, çünkü bayrakları çok iyi çalışmak bütün nedenidir.

 ________________________
 |8|4|2|1|Base 10 Value |
 ------------------------
 |1|1|1|1|15            |
 |1|1|1|0|14            |
 |1|1|0|1|13            |
 |1|1|0|0|12            |
 |1|0|1|1|11            |
 |1|0|1|0|10            |
 |1|0|0|1|9             |
 |1|0|0|0|8             |
 |0|1|1|1|7             |
 |0|1|1|0|6             |
 |0|1|0|1|5             |
 |0|1|0|0|4             |
 |0|0|1|1|3             |
 |0|0|1|0|2             |
 |0|0|0|1|1             |
 |0|0|0|0|0             |
 ------------------------