首页 > 代码库 > 关于+—~有意思的一段C代码

关于+—~有意思的一段C代码

关于+ - ~有意思的一段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,看起来还比较有意思+~-