【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语言中的数据类型转换是程序设计中不可或缺的一部分,它如同连接不同数据世界的桥梁,使得不同类型的变量之间能够互相传递和转换,确保了程序的灵活性与兼容性。通过强制类型转换或自动类型转换,C语言允许开发者在保证数据完整性的前提下,实现复杂的数据处理逻辑。
|
6天前
|
存储 数据建模 程序员
C 语言结构体 —— 数据封装的利器
C语言结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个整体。它支持数据封装,便于管理和传递复杂数据,是程序设计中的重要工具。
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
394 0
|
2月前
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
|
2月前
|
存储 C语言
深入C语言内存:数据在内存中的存储
深入C语言内存:数据在内存中的存储
|
2月前
|
C语言
回溯入门题,数据所有排列方式(c语言)
回溯入门题,数据所有排列方式(c语言)
|
3月前
|
C语言
C语言程序设计核心详解 第二章:数据与数据类型 4种常量详解 常见表达式详解
本文详细介绍了C语言中的数据与数据类型,包括常量、变量、表达式和函数等内容。常量分为整型、实型、字符型和字符串常量,其中整型常量有十进制、八进制和十六进制三种形式;实型常量包括小数和指数形式;字符型常量涵盖常规字符、转义字符及八进制、十六进制形式;字符串常量由双引号括起。变量遵循先定义后使用的规则,并需遵守命名规范。函数分为标准函数和自定义函数,如`sqrt()`和`abs()`。表达式涉及算术、赋值、自增自减和逗号运算符等,需注意运算符的优先级和结合性。文章还介绍了强制类型转换及隐式转换的概念。
|
4月前
|
C语言
【C语言】在限制定条件下数据移动
【C语言】在限制定条件下数据移动
38 1
|
4月前
|
存储 C语言
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
114 4
|
4月前
|
存储 数据可视化 C语言
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】