以下代码的执行结果是().
1 2 3 4 |
int main(){ int i=-2147483648; return printf("%d,%d,%d,%d",~i,-i,1-i,-1-i); } |
正确答案: D 你的答案: C (错误)
A. 0,2147483648,2147483649,2147483647
B. 0,-2147483648,-2147483647,2147483647
C. 2147483647,2147483648,2147483649,2147483647
D. 2147483647,-2147483648,-2147483647,2147483647
解析:
首先要知道-2147483648是32位int所能表示的最小负整数
原码:1000 0000 0000 0000 0000 0000 0000 0000
若按正常的计算补码
取反码:11111 1111 1111 1111 1111 11111 1111 1111
加1:0000 0000 0000 0000 0000 0000 0000 0000就与0的补码一样
所以,规定-2147483648的补码为1000 0000 0000 0000 0000 0000 0000 0000
printf从右向左执行
-1-i :
先求-i : 单目运算符- 表示对该数取反加一(求补运算)
1000 0000 0000 0000 0000 0000 0000 0000取反得01111 11111111 1111 1111 11111 1111 1111
加一得1000 0000 0000 0000 0000 0000 0000 0000即-2147483648
-1的补码:11111 1111 11111111 1111 11111 1111 1111
相加得:01111 1111 1111 1111 1111 11111 1111 1111
该码为正数,原码与补码相同:01111 1111 1111 1111 1111 11111 1111 1111即2147483647
1-i :
已求得-i的补码:1000 0000 0000 0000 0000 0000 0000 0000即-2147483648
1的补码:0000 0000 00000000 0000 0000 0000 0001
相加得1000 0000 0000 0000 0000 0000 0000 0001
该补码的原码为1111 1111 1111 1111 1111 11111 1111 1111即-2147483647
-i:
已求得-i的补码:1000 0000 0000 0000 0000 0000 0000 0000
取反加一的原码:1000 0000 0000 0000 0000 0000 0000 0000即-2147483648
~i:
I的补码:1000 0000 00000000 0000 0000 0000 0000
取反得:01111 1111 1111 1111 1111 11111 1111 1111即2147483647
所以答案为2147483647,2147483648,2147483649,2147483647