一些重要的操作符详解
引言
*如果你是一个初学C语言的人,你可能感觉这些操作符不重要,但是我告诉你,这些非常非常重要,可能刚开始你感觉不到,但是到后面你写的多了,就会感觉到这些问题都是你把操作符没理解好导致的问题!!!
原码 反码 补码
*整数的二进制表示有三种方法:原码,反码,补码。
如果是有符号的表示,要分为两部分:符号位和数值位,最高位的1位被当做符号位,用0表示正数,1表示负数。
原码,反码,补码的转换:将数值直接按照正负数的形式翻译成二进制就得到了原码。
得到原码后,原码的符号位不变,其它位取反得到反码。
反码加1就得到补码。
*补码取反,+1也可以得到原码。
原码 、反码 、补码在计算机中的存储
*刚才想了一下这个问题,真的很重要,在整形中:数据存放在内存中的其实存放的是补码!
原因:使用补码,可以将符号位和数值域统一处理,同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。这个原因是非常重要的!!!可能你现在还不是能理解它!
*证明补码的存储如下:(非常重要)
int main()
{
int a = 10;
//int型是4个字节,32位
// 00000000 00000000 00000000 00001010 -原码、反码、补码
// 00 00 00 0A
int b = -10;
// 10000000 00000000 00000000 00001010
// 11111111 11111111 11111111 11110101
// 11111111 11111111 11111111 11110110
// ff ff ff f6
return 0;
}
移位操作符详解
*这个也非常非常重要!用好了有奇效!!!
<< - - 左移操作符
>> - - 右移操作符
*注意:说的左移和右移都是移动的二进制位。
1) 左移操作符。移位规则是:左边抛弃,右边补0(不管是正数还是负数,还是unsigned,都是这样的规则)
证明如下:
int main()
{
int num = 10;
int a = num << 1;
// 00000000000000000000000000001010 - 原码、反码、补码
//00000000000000000000000000001010
// 00000000000000000000000000010100 -> 4+16 = 20
printf("%d\n", num); //10
printf("%d\n", a); //20
return 0;
}
1) 左移操作符,分为下面两种:
*逻辑右移:左边用0填充,右边丢弃
*算数右移:左边用原该值的符号位填充,右边丢弃。
一个计算机到底是逻辑右移还是算数右移,这个是由造计算机的人决定的,不是我决定的.
证明如下:
int main()
{
int num = -10;
int a = num >> 1;
// 10000000 00000000 00000000 00001010 - 原码
// 11111111 11111111 11111111 11110101 - 反码
// 11111111 11111111 11111111 11110110 - 补码
// 11111111111111111111111111110110
// 11111111111111111111111111110110
// 11111111111111111111111111111011 - 右移之后的补码
// 10000000000000000000000000000100 -反码
// 10000000000000000000000000000101 -(-5) - 源码
printf("%d\n", num); //-10
printf("%d\n", a); //-5
//算数右移具有/2的效果
return 0;
}
注意:不要移动负数位,这个是标准未定义的。
详解位操作符
位操作符有:&(按位与) 、|(按位或)、 ^(按位异或)、 ~(按位取反)这四种操作符(同样操作的是二进制)
int main()
{
int num1 = -3;
// 10000000 00000000 00000000 00000011 - 原
// 11111111 11111111 11111111 11111100 - 反
// 11111111 11111111 11111111 11111101 - 补
// ff ff ff fd
int num2 = 5;
// 00000000 00000000 00000000 00000101 -原,反,补
// 11111111111111111111111111111101
// &
// 00000000000000000000000000000101
// 00000000000000000000000000000101 - 5
printf("%d\n", num1 & num2); //5
// 11111111111111111111111111111101
// |
// 00000000000000000000000000000101
// 11111111111111111111111111111101 - 补
// 10000000000000000000000000000010 - 反
// 10000000000000000000000000000011 - (-3)原
printf("%d\n", num1 | num2); //-3
// 11111111111111111111111111111101
// ^
// 00000000000000000000000000000101
// 11111111111111111111111111111000 - 补
// 10000000000000000000000000000111 - 反
// 10000000000000000000000000001000 - 原(-8)
printf("%d\n", num1 ^ num2);//-8
return 0;
}
完结!!!