1.什么叫整形提升,就得搞清楚什么是整形。这里不过多介绍。这里知识会涵盖,下列介绍时也会用到,希望大家先去搜搜其他得博客或者书籍了解一下。
首先整形家族有:char ,short(short int), int ,long,long long。上述类型都可以在前面加unsigned变成无符号数(二进制里面得第一位不作为符号位,作为计数位)。这里说明,char相当于是整形,因为存得字符实际上是ASCII码值,所以也算整形。
如:
char a = 98;
printf("%c", a);
printf("%d", a);
打印结果就是“b”字符,所以char算是整形,下一个打印又是98。
整形提升与整形截断
那么就进入整形提升,这里就涉及到C语言数据存储。我们知道,整形数据实际在机器里面是以补码来进行运算得。并且是以补码进行的。那么当把一个char类型的数据赋值给int是怎么样的呢。这里面涉及整形提升。
char a = 128;
int b = a;
printf("%d", a);
printf("%d",b);
这里a的值是多少呢?
打印发现,a,b的值是-128.那为什么会这样呢。就是整形提升和整形截断的原因。
在存储数据的时候,实际机器是以二进制的补码进行存储和运算的。运算关系是:符号位不变,原码就是数据直接转换位二进制的码,反码是原码每位二进制位按位取反,反码加一得到补码。
如果是无符号数或者是正数,就三码相同
整形截断
而char 1个字节:8个bit位
int 4个字节:32个bit位。
char a = 128;//这里其实存储的时候已经存在整形截断了,128这个常量一般在C语言里面就默认成一个整形,你可以把鼠标放在上面看下。
那么128三码:
反码:00000000000000000000000010000000
反码:1111111111111111111111111111011111111
补码:111111111111111111111111111110000000
而由于存储的时候,只能由八个字节,也就是8个二进制位。那么前面的就会砍掉,只留下最后面八位,作为a的补码存入储存器。
那么a所储存的补码就是10000000;这就是我们常说的整形截断。
接下来就是整形提升,那么你在把a的值赋值给整形,或者以整形打印。
整形提升的规则:有符号数,整形提升时补充符号位。无符号数补充时,补充0;
那么这里a的补码就要整形提升,且a是有符号数,那么就补充1,
a的整形补码形式:11111111111111111111111110000000;
其所对应的反码: 111111111111111111111111101111111;
对应的原码: 10000000000000000000010000000;//有符号数,那么就是-128
者就是char对应的整形提升,对应的short, 是类似的。
再来看非符号数,这里讲一下整形截断来举例,非符号数整形提升按照上述规则来即可。
unsigned char a ;
int b = 256;
a = b;//其结果是多少呢?
printf("%d\n",a);//打印结果是0;
上述原理类似;可以尝试求出b的补码。
b 的补码:00000000000000000000000100000000;
那么把这个进行整形截断,只取后八位,则全部都是0;
这个全部都是0的补码,自然对应的打印结果就是0;
算术转换
算术转换:当int 遇见float,unsigned int ,unsigned float,long ,longlong,unsigned long等比int长或者是,那么int就会转换位对应算法,和整形提升类似。int就换发生变化,转换位对应类型数据
根据算术转换的规则,一种类型遇见类型更高的类型,要进行算术转换。
从低到高具体是int ,unsigned int ,long ,unsigned long, longlong ,unsigned long long ,float, unsigned float ,double float ,
int转换为float,因为float表示范围更大。且float型储存方式不太一样。具体查IEEE标准
这里以int和float举例子。
int a = 300;
float b = 1.23;
printf("%f",a + b);
打印结果:301.230011;尾数的11于IEEE标准有关,就是在转换的一些问题。这里不做赘述。
在300转换的时候,符号位依然是符号位,但是会转换为二进制的科学计数法,并且储存。进行加减即可。
printf("%d",a + b);//536870912
这里在打印结果的时候,我们发现结果很大,原因就是在计算的时候,会根据顺序进行算术转换,那么结果就是算术转换之后的结果也就是float型,但是这里打印整形,在二进制储存之中,float储存方式不同,但是字节大小却一样。那么系统在打印的时候,会把其当做整形,从而进行打印,导致了最终的打印结果的差异。具体可以了解IEEE标准后去计算。
printf("%f \n", a);0。0000000
这里原因类似,因为储存方式不同,运行的时候,所读取的结果也不一样。
本文章为学习之后总结的笔记型。欢迎错误和补充