3.表达式求值
3.1.隐式类型转换:
表达式中的字符和短整形操作数在使用之前都会被转换为普通整形(int)类型,这种转换称为整形提升。
那么电脑是如何整形提升的呢?
负数和正数的整形提升:
补最高位
eg:
char c=-1;
11111111
111111111111111111111111111111111111111
char b=1;
0000001
0000000000000000000000000000000001
无符号的整形提升:
高位补0
例子1:
int main() { char a = 0xb6; short b = 0xb600; int c = 0xb6000000; if(a==0xb6) printf("a"); if(b==0xb600) printf("b"); if(c==0xb6000000) printf("c"); return 0; }
实例1中的a,b要进行整形提升,但是c不需要整形提升
a的二进制是 0000 0000 1001 0110
截断后是 1001 0110
整形提升后是1111 1111 1001 0110
反码1000 0000 0110 1001
原码1000 0000 0110 1010
a,b整形提升之后,变成了负数,结果是假,但是c不发生整形提升,则表达式的结果是真.
所程序输出的结果是:c
例子2:
int main() { char c = 1; printf("%u\n", sizeof(c)); printf("%u\n", sizeof(+c)); printf("%u\n", sizeof(-c)); return 0; }
实例2中的,c只要参与表达式运算,就会发生整形提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节.
表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof c ,就是1个字节
3.2算术转化:
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。排名顺序如下:
4.整形存储的例子
例子1:
a和b都是有符号char
10000000000000000000000000000001
11111111111111111111111111111110
11111111111111111111111111111111
11111111 - a 截断
11111111111111111111111111111111 - 提升
c是无符号char,提升的时候补0
10000000000000000000000000000001
11111111111111111111111111111110
11111111111111111111111111111111
00000000000000000000000011111111
答案是a=-1,b=-1,c=255
注意:
%d在读取时会读取符号位,而%u在读取时不会读取符号位!
例子2:
-128的原反补如下:
10000000000000000000000010000000
11111111111111111111111101111111
11111111111111111111111110000000 -128的补码
10000000 - a
整形提升后:
11111111111111111111111110000000
以%u的视角读取时,不会读出符号位,所以答案是一个很大的数字4,294,967,168。
例子3:
128的原反补如下:
00000000000000000000000010000000
01111111111111111111111101111111
01111111111111111111111110000000 -128的补码
10000000 - a
整形提升后:
11111111111111111111111110000000
以%u的视角读取时,不会读出符号位,所以答案是一个很大的数字4,294,967,168。
例子4:
int i = -20
10000000000000000000000000010100
11111111111111111111111111101011
11111111111111111111111111101100
unsign int j=10;
00000000000000000000000000001010
相加得:
11111111111111111111111111110110 - 补码
11111111111111111111111111110101
10000000000000000000000000001010
答案是-10
例子5:
我们知道unsigned int的范围一定是大于等于0的,所以当无符号的i=0时–会得到非常大的数字,会变成一个死循环,
因为0-1等于-1,
-1的补码为1111111111111111
而无符号数不看符号位,所以是很大的数4,294,967,295
具体循环为:
9 8 7 6 5 4 3 2 1 0 4,294,967,295 4,294,967,294…
例子6:
补充:
我们知道有符号char的范围是-128到127并且是一个轮回(因为超出范围后截断,还是在这个范围内)
所以这一题目的循环是-1 -2…-128 127 126 125…0 -1 -2 -3…-128 127—而我们知道,strlen在发现\0就会停止,所以a数组的长度为255.
例子7:
一样的,我们知道无符号char的范围是0到255,所以当i=255时再加1,会进1,使截断后全为0,所以255+1以后又变成0,又是一个死循环了。
总结
本站主要讲解了数据的基本类型、原码反码补码、大小端和整型的存储
这里我们额外要记住的是:
整型提升补的数字是又变量类型决定的,%d和%u只是决定了读取的时候是否读取符号位。
如果对你有帮助,不要忘记点赞加收藏哦!!!
想获得更多优质的博客,一定不要忘记关注我哦!!!
更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!