C&PHP:使用按位运算符将整数设置存储?

我不熟悉按位运算符,但我似乎以前用它们来存储简单的设置。

我需要将几个开/关选项传递给一个函数,我想为此使用一个整数。 我该如何设置和阅读这些选项?

你肯定可以用PHP做到这一点。

假设您要将四个布尔值存储在单个值中。 这意味着我们需要四位存储空间

0000 

单独设置时,每个位都有一个十进制的唯一表示

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

实现此目的的常用方法是使用位掩码来表示每个选项。 例如,PHP的错误级别就是以这种方式完成的。

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

然后当你有一个表示0或更多这些标志的整数时,你用bitwise和operator检查是&

 $options = bindec( '0101' ); // can also be set like this // $options = OPT_1 | OPT_3; if ( $options & OPT_3 ) { // option 3 is enabled } 

此运算符的工作方式如下:在结果中仅设置在两个操作数中设置的位

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

如果我们针对OPT_2进行了检查,那么结果将如下所示

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

它在两种语言中的工作方式大致相同,并列比较:

C:

 #include  #include  #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:

  

注意,你并不一定需要使用常量,我只是出于习惯而使用它们。 这两个例子都会运行,我通过gcc -Wall flags.c -o flags编译了C版本。 将示例中的flags更改为除FLAG_TWOFLAG_ALL任何内容,并且(遗憾地)不会FLAG_TWOFLAG_TWOcookies。

在C版本中,您不必搔痒预处理器,它可以很容易地成为枚举等 – 这对读者来说是一种练习。

引用“这个想法并不好,真的。你最好传递一些布尔值。如果你想用bitwise那么

 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 } 

如果你检查单个值,虽然不是最佳值,你所做的就没关系,所以检查一下是否启用了,但是我们想要能够匹配任何一个,或者确切地说我们可以使用以下方法

 function matchExact($ in,$ match){//符合你的标准,就像一个开关,case,但最终不适合用于标志
     return $ in === $ match;
 }

 function matchAny($ in,$ match){//符合具有更多词法名称的原始标准但是如果任何标志为true则返回true
     return $ in | = $ match;
 }

如果您想通过仅在启用位x,y,z的情况下执行特定操作来扩展此function,那么您可以使用以下内容

 function matchHas($ in,$ match){//比_ =更按位,允许你有条件地分支设置的特定位
     return $ in&= $ match;
 }

我也认为如果你正在做上面引用中所做的事情,标志可能不是最好的主意,确切的值可能更好,这确实有利于允许更谨慎的行动。 (0-255)用于8位超过8个不同的标志

整个原因标志工作得很好是因为在基数2“8”中不包含“4”,而“2”不包含“1”。

  ________________________
  | 8 | 4 | 2 | 1 |基数10值|
  ------------------------
  | 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 |
  ------------------------