不确定如何获得输出!位字段

时间:2016-03-06 23:45:16

标签: output bit-fields

我一直在看这段代码。我知道输出是50但不确定这是怎么发生的。

if (isset($_GET['mac'])) { 
    if (strlen($_GET['mac']) == 18) { 
        $get_mac_filtered = preg_replace('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', '',$_GET['mac']);
            if (preg_match('/^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/', $_GET['mac']) == $get_mac_filtered) {
                echo 'Got a mac match! '.$get_mac_filtered;
            }else {
                echo 'Sorry !=';
            }
}else {die();} }

有人可以提供任何帮助,我真的很感激。

1 个答案:

答案 0 :(得分:1)

嗯,似乎是一个带有连续位域的结构被压缩,当用printf格式说明符传递给%d时,这就像某种“位”聚合“(见注)。经过一些不同的测试,我想出了以下方案:

结构成员(位域)因此对齐:

n n n n n m m m

即以“降序”顺序 - 最后一次出现。

然后,在main中, bm 获取值2,二进制为10,3位格式为010, bn 获取值6,二进制为110,5位格式为00110,因此最终得到00110010,其dec值为... 50.

为了进一步测试这个假设,我用另外一个成员扩展了b struct并检查它是否仍然成立:

#include <stdio.h>

struct { 
    unsigned m : 3;
    unsigned n : 5;
    unsigned o : 5;
} b;

int main(void) {
    b.m = 1;
    b.n = 1;
    b.o = 1;
    printf("%d\n",b);
    return 0;
}

根据假设,结构成员应该以这种方式对齐:

o o o o o n n n n n m m m

并且在main中分配给它们的值(即1,1和1),这将导致二进制0000100001001,其在dec中为265.

编译并运行产量:

$ gcc -Wall -o stprint stprint.c
stprint.c: In function ‘main’:
stprint.c:13:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘struct <anonymous>’ [-Wformat=]
     printf("%d\n",b);
     ^
$ ./stprint
265

即(最有可能)验证假设的结果。 希望我对这种行为有所了解。

编辑/注意:如果从上面不清楚,正如其他评论者指出的那样,这种行为取决于实现,这意味着由编译器决定是否“比特聚合“发生与否,具体顺序是什么。还必须考虑底层平台的字节顺序(例如,请参阅here)。这篇文章gcc version 4.8.4用于Ubuntu系统。