一、原码、反码、补码
根据本人自己的理解:
- 原码就是一个数字的二进制。
- 反码是原码的符号位不变,其余位置取反(0→1,1→0)。(符号位就是最高位,0代表正,1代表负)
- 补码就是反码加1。(计算机中存的是补码而不是原码)
以上建立在有符号位的基础上,因为无符号位的话,原码、反码。补码是相同的。
在C语言中默认都是有符号位的。如果无符号位要加上unsighd。如:unsigned int a=10;
例子:比如在C语言中一个int型是4个字节。(一个字节8个比特位)
int a=10;这个:
原码为:00000000000000000000000000001010 反码为:01111111111111111111111111110101 补码为:01111111111111111111111111110110
了解原码,反码,补码之后就是做题加深理解。
二、练习题
这些题都是出自公司笔试题所以不要想着敲出来,否则没什么意义。
第一题
//输出什么? #include <stdio.h> int main() { char a = -1; signed char b = -1; unsigned char c = -1; printf("a=%d,b=%d,c=%d", a, b, c); return 0; }
第二题
//输出什么? #include <stdio.h> int main() { char a = -128; printf("%u\n", a); } //%d是打印十进制有符号的数字 //%u是打印十进制无符号的数字
第三题
//输出什么? #include <stdio.h> int main() { char a = 128; printf("%u\n", a); }
三、题目解析
第一题
分析可知a和b都是有符号的,结果应该是一样的。
-1的原码,反码,补码如下:
原码:10000000000000000000000000000001 反码:11111111111111111111111111111110 补码:11111111111111111111111111111111
因为是char类型的只能存8个比特位,所以要截断后8位是(截断的是补码):
11111111
但是题目要求打印有符号的十进制并且是整型,所以要整型提升为:
11111111111111111111111111111111
以上是补码转换为反码就是减1为:
11111111111111111111111111111110
反码转化为原码就是符号位不变,其余取反为:
10000000000000000000000000000001
所以a和b的结果都是-1;
c截断的补码是
11111111
但是由于c是无符号位所以整型提升后是:
00000000000000000000000011111111
因为无符号位的原码,反码,补码相同。最终结果就是255。
综上结果是a=-1,b=-1,c=255
第二题
-128:
原码是:10000000000000000000000010000000 反码是:11111111111111111111111101111111 补码是:11111111111111111111111110000000
char类型要发生截断为:
10000000
但是要求打印十进制无符号位要进行整型提升为:
11111111111111111111111110000000
因为%u是无符号位所以原码,反码,补码相同。
结果是4294967168
第三题
128,char类型是8个比特位最大值是:
01111111
这个是char类型可以存的最大正数为127,如果加1变为
10000000 C语言中规定这个数的十进制是-128;
所以结果和第二题结果一样为4294967168
四、整型提升
整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。
提升规则:如果有符号按照符号补全如(10001111整型提升为11111111111111111111111110001111)