关于+ - ~有意思的一段C代码
问题是钟哥几天前在automation的群里面抛出来的。
code:
#include <stdio.h>
int main(int argc,char* argv[])
{
int a = 7;
int b = 1;
printf("before process,a = %d,b = %d\n",a,b);
b = +~ +~ +~ +~ + ~~a;
printf("after process,a = %d,b = %d\n",a,b);
return 0;
}
请问这段代码能过编译吗?
如果能过,ab最后的值是多少?
当然,我给出了解释的时候就会变得“这又什么意思咯,原来如此。。。”
既然到了把问题记录到blog的份上,代码肯定能过编译的,不然故事就没法继续编了。。。哈哈
一般的+用法都是 varible1+varible2; 是所作为双目operator。这里居然和+~混着用。一眼看去,貌似很乱,居然还能过编译
这里没有很“权威的说法”,C标准并没管这事,得出的结论是测试性的
+被用作单目操作符,表示数的正负。
也就是说+a 表示不改变a原来的符号,如果是个负数就是负数,是个正数就是正数。
如果是-a就是取a的相反数
b = +~ +~ +~ +~ + ~~a;
这里的~也就是普通的取反,这里+几乎不起作用,因为不改变a的值,~取反(bit inverse )6次,于是这里相当于b = a;
最后ab的值也分别是7 7
liuzjian@ubuntu:~/Desktop$ ./a.out
before process,a = 7,b = 1
after process,a = 7,b = 7
我们对代码稍作修改,继续对问题进行探讨
把+部分改成-,其他的不变,一步步的分析operator对a值的操作
#include <stdio.h>
int main(int argc,char* argv[])
{
int a = 7;
int b = 1;
printf("before process,a = %d,b = %d\n",a,b);
b = -~ -~ -~ +~ + ~~a;
printf("after process,a = %d,b = %d\n",a,b);
return 0;
}
首先~~a对a取反两次,得到的值还是7,接着遇到第一个+,值不变,接着遇到~,此时bit inverse,a 由 0x00000007(假设32bit的机器)变成0xfffffff8 , 接着遇到第二个+,值不变,接着遇到~,变回原来的0x00000007接着遇到-,变成-7,机器表示为0xfffffff9,再遇到~,取反,得到0x00000006,遇到-,即变-6,机器码为0xfffffffa,再遇到最后一个~,变成0x00000005,接着遇到最后的-,得到-5,赋值给b。
It was done!
liuzjian@ubuntu:~/Desktop$ ./a.out
before process,a = 7,b = 1
after process,a = 7,b = -5
Ok,看起来还比较有意思+~-