1.整型在内存中的截断:
以下面的图进行举例:
此代码的运行结果的图为
那为什么此图的结果和我们预想的不一样呢?
那是因为整形数据的 默认类型是int类型,如图中的300的默认类型就是int类型
所以此时如果把300按整型数据则它的二进制补码为0000 0000 0000 0000 0000 0001 0010 1100
但此时我们要把数据存入比它小的char类型,那就要发生截断,截断要从右向左截断,还要根据数据类型的字节长度来截合适的长度,截断时此时char类型内存的二进制就变为 0010 1100;而此时我们要用"%d"的形式打印出来,就由要整型提升,此时char类型的符号位是0,所以要补够int类型
此时就是char类型整型提升就变为0000 0000 0000 0000 0000 0000 0010 1100;所以打印出来的值就变为了44;
总结:发生截断的时机:1.如果大的数据类型存入小的数据类型,就会发生截断;
2.如果没有大的数据类型,但我们要把一个数据存入char或short时,但一 个数据的默认类型时int类型,所以此时也会发生截断;
注意:在内存中的截断的载体形式时二进制补码;
当实数类型存入整数类型时也会发生截断;
2.整型类型在内存中的整型提升
整型提升是C程序设计语言中的一项规定: 在表达式计算时 ,各种整形首先要提升为int类型。 表达式的整型运算要在CPU的相应运算器件内执行,CPU内的整型运算器的操作数的字节长度一般是int 类型的字节长度,即四个字节。 因此即使是两个char( char类型为一个字节)类型的数相加,在CPU相应的运算器件中也很难直接进行相加,这时候就要进行整型提升到四个字节才能进行相加计算。
整型提升的规则: 整型提升分为有符号和无符号两种:
有符号的:整型提升时是按照变量的补码被截断时的最高位是什么进行补位的,如果截断后最高位即最左面的一位数为 1 则在最高位前补 1 ,如果最高位是 0 则在前面补 0 ,补够32位即int类型即可。
无符号的: 直接在被截断的前面补 0 即可。
注意:此时参与表达式类型的计算都比int类型还要小时,计算时就要转换为整型类型,这就是整型提升
如下图所示:
-138的默认类型为int类型,所以二进制原码为1000 0000 0000 0000 0000 0000 1000 1010
存入内存的则变为补码: 1111 1111 1111 1111 1111 1111 0111 0110,因为要存入char类型a中所以要发生截断,因为是在内存中截断,所以char a的二进制补码为0111 0110;
-126的默认类型为int类型,所以二进制原码为1000 0000 0000 0000 0000 0000 0111 1110
存入内存的则变为补码: 1111 1111 1111 1111 1111 1111 1000 0010,因为要存入char类型b中所以要发生截断,因为是在内存中截断,所以char b的二进制补码为1000 0010;
又因为a + b,又因为内存中的运算器时在运算时类型至少是int类,所以a和b要进行整型提升,
所以a整型提升后为0000 0000 0000 0000 0000 0000 0111 0110;
b整型提升后为1111 1111 1111 1111 1111 11111 1000 0010;
因为内存中的所有运算都在二进制补码中进行则
a + b为1111 1111 1111 1111 1111 1111 1111 1000;
又因为要存入char c中则要截断所以c为1111 1000;
又因为printf打印时用的%d的型式,所以c在内存中的二进制补码要进行整型提升
所以c为1111 1111 1111 1111 1111 1111 1111 1000;
又因为要转化成原码显示所以c的原码1000 0000 0000 0000 0000 0000 1000;
所以c的结果为-8;
3.算术类型转换
但当进行表达式计算时,而类型不同时,此时就要进行算术类型转换
下面为算术类型转换的图: