请告诉程序末尾声明的 main 是如何工作的,并 '\' use.Output s 0
#define P printf("%d\n", -1^~0);
#define M(P) int main()\
{\
P\
return 0;\
}
M(P)
请告诉程序末尾声明的 main 是如何工作的,并 '\' use.Output s 0
#define P printf("%d\n", -1^~0);
#define M(P) int main()\
{\
P\
return 0;\
}
M(P)
宏展开后相当于:
int main() { printf("%d\n", -1^~0); return 0; }
然后~0
在-1
一个二进制补码系统 -1 ^ ~0
中,就像一个数字与它本身的异或-1 ^ -1
一样。0
0
编译gcc
并添加-E
选项(即,在预处理后停止并输出预处理代码),揭示了正在发生的事情:
# 1 "output.c"
# 1 "<command-line>"
# 1 "output.c"
int main() { printf("%d\n", -1^~0); return 0; }
基本上你只是打印一个整数:-1^~0
。
这等价于-1 XOR 0xFFFFFFFF
(假设这里的整数是 32 位),因为1
(即 的表示-1
)的二进制补码是0xFFFFFFFF
,所以总是输出0
( 1 XOR 1 == 0
)。
通过预处理器,您的代码将扩展为:
int main()
{
printf("%d\n", -1^~0);
return 0;
}
~0
是0
所有位的1 的补码1
(在大多数实现中)。
0000 0000 0000 0000 0000 0000 0000 0000 = 0
1111 1111 1111 1111 1111 1111 1111 1111 <== ~0 , compliment each bit
所以假设如果你有 32 位 int:
-1
是 2'c 的补码,1
所有位都为 1:
0000 0000 0000 0000 0000 0000 0000 0001 <== 1
1111 1111 1111 1111 1111 1111 1111 1110 <== 1's complement of 1
1111 1111 1111 1111 1111 1111 1111 1111 <== 2's complement of 1
所以-1^ ~0
输出: 0
因为在^
is XOR
- 运算符和1 xor 1 = 0
.
~0 == 1111 1111 1111 1111 1111 1111 1111 1111
-1 == 1111 1111 1111 1111 1111 1111 1111 1111
------------------------------------------- Bitwise XOR
~0 ^ -1 == 0000 0000 0000 0000 0000 0000 0000 0000
在这里查看XOR 的工作原理。
利用:
gcc -E <file_name>.c
-E 仅预处理;不要编译、汇编或链接
输出:
int main() { printf("%d\n", -1^~0); return 0; }