我对位运算符并不熟悉,但我见过它们用于存储简单的设置。
我需要将多个开关选项传递给一个函数,并且希望只使用一个整数来实现。我该如何设置和读取这些选项?
我对位运算符并不熟悉,但我见过它们用于存储简单的设置。
我需要将多个开关选项传递给一个函数,并且希望只使用一个整数来实现。我该如何设置和读取这些选项?
你肯定可以用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或多个这些标志的整数时,你可以使用按位与运算符&
进行检查。
$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 <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);
?>
gcc -Wall flags.c -o flags
编译了C版本。在任何一个示例中将flags
更改为除FLAG_TWO
或FLAG_ALL
之外的任何内容,(遗憾地)将不会制作华夫饼。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
}