整形提升
关于表达式的隐式类型转换和整形提升,详见下面链接:
整形提升
对于整形提升,高位需要补位,那么补什么呢?
无符号数高位补0,有符号数高位补1;
例题详解:
例题1:
下面代码的输出结果是什么呢?
#include <stdio.h>
int main()
{
char a = -1;
signed char b = -1;
unsigned char c = -1;
printf("a=%d b=%d c=%d\n", a, b, c);
return 0;
}
结果是什么呢?
结果是,a=-1,b=-1,c=255,这是为什么呢?
-1在内存中的存储补码为:11111111 11111111 11111111 11111111
-1转换为char a需要发生截断,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是有符号数补符号位,高位补1,
即:11111111 11111111 11111111 11111111 ——> -1
-1转换为signed char b需要发生截断,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是有符号数,补符号位,高位补1,
即:11111111 11111111 11111111 11111111 ——> -1
-1转换为unsigned char c需要发生截断 ,截断后为:1111 1111,但是在输出的时候,是按照%d整型打印,所以需要整形提升,是无符号数高位补0,
即:00000000 00000000 00000000 11111111 ——> 255
例题2:
下面代码的输出结果是什么呢?
#include <stdio.h>
int main()
{
char a = -128;
printf("%u\n", a);
return 0;
}
结果是:128吗?
为什么结果会是这个呢?
-128在内存中的存储补码为:11111111 11111111 11111111 10000000
转换为char型,发生了截断,变为:10000000;
按照%u打印,先进行整形提升,是有符号数,补位符号位,
变成:11111111 11111111 11111111 10000000
最后按照无符号数打印,最高位不是符号位了,所以结果是232-127
注意:
整形提升的时候,看的是原本的类型。
例题3:
那么下面代码的输出结果是什么呢?
#include <stdio.h>
int main()
{
char a = 128;
printf("%u\n", a);
return 0;
}
和例题2相比,这道题的结果是什么呢?
结果是128了吗?
为什么结果会是这个呢?
128在内存中的存储补码为:00000000 00000000 00000000 10000000
转换为有符号的char型,发生了截断,变为:10000000;
按照%u打印,先进行整形提升,是有符号数,补位符号位,
变成:11111111 11111111 11111111 10000000
最后按照无符号数打印,最高位不是符号位了,所以结果是232-127
例题4:
那么下面代码的输出结果是什么呢?
#include <stdio.h>
int main()
{
int i = -20;
unsigned int j = 10;
printf("%d\n", i + j);
return 0;
}
结果是多少呢?
i的原码:10000000 00000000 00000000 00010100
i的补码:11111111 11111111 11111111 11101100
j的补码:00000000 00000000 00000000 00001010
相加:11111111 11111111 11111111 11110110
按照%d有符号的打印,则:结果为-10
其实在无符号和有符号数相加的时候发生了隐式类型转换,往大了转。
例题5:
那么下面代码的输出结果是什么呢?
#include<stdio.h>
int main()
{
unsigned int i;
for (i = 9; i >=0; i--)
{
printf("%u\n", i);
}
return 0;
}
是输出9——0吗?
结果是死循环:
为什么呢?
因为i是一个无符号的数,i - -,每次减少1,当i等于0 的时候,i=0,然后i - -的时候,是-1,-1整形提升为无符号的数,那么就是一个非常大的数字一直减减,所以会成为死循环。
例题6:
观察下面代码,结果是多少呢?
#include <stdio.h>
int main()
{
char a[1000];
int i;
for (i = 0; i < 1000; i++)
{
a[i] = -1 - i;
}
printf("%d\n", strlen(a));
return 0;
}
分析:
在- 1 - i 的时候发生提升,转换为整型计算,计算完赋值给char数组a的时候,发生截断,只取1个字节,即:后8位。
strlen求长度,遇到‘\0’,就会停止;而‘\0’,的ASCII码是0;所以当后8位为0,就能求出长度。
-1 - i,需要-256次才能保证后8位全为0,但是‘\0’,并不计算进strlen长度,所以结果是255。
结果:
例题7:
观察下面代码,判断结果是:
#include <stdio.h>
int main()
{
unsigned char i = 0;
for ( i = 0; i <= 255 ; i++)
{
printf("hello world\n");
}
return 0;
}
分析:
因为 i 是无符号的char型,char只看1个字节8位,所以i发生了截断和提升,当i从0一直++,会从0一直到255,而当再次++的时候,发生截断,256的后8位是0000 0000 所以i再次变为0,所以程序会死循环。
可是,如果将i<=255改成i<255,那么程序就不会变为死循环,而是打印255次就会结束