【生僻字系列】C语言生僻符号‘~’背后隐含的大秘密
我们都知道,在C语言中有一个这样的运算符‘~’,那它到底是什么意思呢?且听我细细分析。
首先给大家先来一段代码体会一下这个运算符的神奇之处
#include<stdio.h>
int main(){
int a=0;//赋值
int b=~a;//功能实现
printf("%d\n",b);
return 0;
}
运行结果如下所示:
让我们惊奇的是,b竟然取值为-1,与a=0的原取值完全不同,那么,两者之间的关系究竟是如何的呢?
其实说到底符号‘~’是一种按位(二进制位)取反的运算符,讲到按位取反,又不得不提到数据的存储问题。
首先我们都知道数可以分为正数,0,负数,而在c语言中数分为有符号数(如-1)和无符号数,需要注意的是0在计算机中有+0与-0的区分,而数据以补码的形式存储,这里又要科普原码,反码,补码之间的相爱相杀的关系了。
关系总结如下:
原码按位(二进制位)取反(如0变为1)得反码,反码加1得补码,下面我会提供示例供读者参考(以数字0为例)
0在计算机种分+0与-0,它们的原码,补码,反码如下:
1、[+0]原码=0000 0000
2、[+0]反码=0000 0000
3、[+0]补码=0000 0000
在这里你会发现,+0的原码,反码,补码都相同,这并不是一个巧合,实际上只要是正数它的原、反、补码都相同
而对于有符号数而言最高位为符号位,故原码——>补码时不用取反,其他位按位取反即可,之后最高位由于进位导致高位变0
[-0]原码=1000 0000
[-0]反码=1111 1111
+0000 0001
------------------
[-0]补码=0000 0000
到这你也将会看到+0与-0的补码是一样的,即0的补码只有一种表示,所以也体现出用补码存储数据的好处。
所以看到这里,我们也就大致能够明白符号’~‘的运算规则了,所以回到本题,a=0,b=~a;(此题的b为有符号的整形)
所以先写出a的补码:00000000000000000000000000000000
按位取反得b的补码:1111111111111111111111111111111111111
在求其反码: 1111111111111111111111111111111111110
在求其原码: 10000000000000000000000000000001(-1)
故b的值为-1,当读者看到这时,要注意一点的是计算机打印的数据是以原码形式打印的,存储以补码形式存储的。
文章写得比较匆忙,有问题还请各位大佬指出错误!