我一直在看这段代码。我知道输出是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();} }
有人可以提供任何帮助,我真的很感激。
答案 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系统。