【c语言进阶】深度剖析整形数据(二)

简介: 【c语言进阶】深度剖析整形数据(二)

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算术转化:


如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。排名顺序如下:


e4fce21ecd66ed91c1b011bf15add620_a7c3cc40fabd49529b6e3a87b4e59b99.png


4.整形存储的例子


例子1:


b36be1ac23990942fb44566aca3e6184_720c5b031629421282cf2bc30e6186d4.png


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:


888c362d50e3799a1eb05ce8b8c8f1ff_eed83d7c1f8e46f39848a8a646ec393e.png


-128的原反补如下:

10000000000000000000000010000000

11111111111111111111111101111111

11111111111111111111111110000000 -128的补码

10000000 - a

整形提升后:

11111111111111111111111110000000

以%u的视角读取时,不会读出符号位,所以答案是一个很大的数字4,294,967,168。


例子3:


7e905d84a5d37ef3999e89f594a77965_623ec31fadfe459f8a368e64985f3ba7.png


128的原反补如下:

00000000000000000000000010000000

01111111111111111111111101111111

01111111111111111111111110000000 -128的补码

10000000 - a

整形提升后:

11111111111111111111111110000000

以%u的视角读取时,不会读出符号位,所以答案是一个很大的数字4,294,967,168。


例子4:


34a6fc49b681780764373fe3e33786ad_61e6025a078e49779cc61bbd9c2b810a.png


int i = -20

10000000000000000000000000010100

11111111111111111111111111101011

11111111111111111111111111101100

unsign int j=10;

00000000000000000000000000001010

相加得:

11111111111111111111111111110110 - 补码

11111111111111111111111111110101

10000000000000000000000000001010

答案是-10


例子5:


28d6d24b22618a4b9fabfe046d8ba67e_d1469a4c12514620bb196e1d25387d96.png


我们知道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:


83a019cd786f9ac04669b3d9d0a2a604_97010aebc5ac4e9485c00dbceb291018.png


补充:


我们知道有符号char的范围是-128到127并且是一个轮回(因为超出范围后截断,还是在这个范围内)


153782ebb41aa7dd8e717f23d94961af_1f63a702c93e49868a64b553401edbba.png


c3c92b8d11d00d78eb59c05b37e05dab_3dececc04b6d432d9773da73e1604c53.png


 所以这一题目的循环是-1 -2…-128 127 126 125…0 -1 -2 -3…-128 127—而我们知道,strlen在发现\0就会停止,所以a数组的长度为255.


例子7:


ddb22f538efc87e582514c4e92ee60ba_15a9372370c54e4abfe07a71648d282f.png


一样的,我们知道无符号char的范围是0到255,所以当i=255时再加1,会进1,使截断后全为0,所以255+1以后又变成0,又是一个死循环了。


总结


本站主要讲解了数据的基本类型、原码反码补码、大小端和整型的存储


这里我们额外要记住的是:


整型提升补的数字是又变量类型决定的,%d和%u只是决定了读取的时候是否读取符号位。


如果对你有帮助,不要忘记点赞加收藏哦!!!


想获得更多优质的博客,一定不要忘记关注我哦!!!


 更新不易,辛苦各位小伙伴们动动小手,👍三连走一走💕💕 ~ ~ ~ 你们真的对我很重要!最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

目录
相关文章
|
2天前
|
存储 编译器 程序员
C语言:数据在内存中的存储
C语言:数据在内存中的存储
13 2
|
2天前
|
存储 C语言
C语言进阶---------作业复习
C语言进阶---------作业复习
|
2天前
|
存储 Linux C语言
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-2
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
2天前
|
自然语言处理 Linux 编译器
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)-1
C语言进阶第十一节 --------程序环境和预处理(包含宏的解释)
|
2天前
|
存储 编译器 C语言
C语言进阶第十课 --------文件的操作-1
C语言进阶第十课 --------文件的操作
|
2天前
|
存储 程序员 C语言
C语言进阶第九课 --------动态内存管理-2
C语言进阶第九课 --------动态内存管理
|
2天前
|
编译器 C语言
C语言进阶第九课 --------动态内存管理-1
C语言进阶第九课 --------动态内存管理
|
2天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
16小时前
|
C语言
C语言——函数递归
C语言——函数递归
4 0
|
16小时前
|
C语言
C语言—函数(大化小方式的心脏)
C语言—函数(大化小方式的心脏)
2 0