隐式类型转换的陷阱
//输出什么? #include <stdio.h>
int main() {
char a= -1; //第一次隐式类型转换,-1是int型,要被隐式转换为有符号char型
signed char b=-1; // 跟上面一样,-1是int型,要被隐式转换为有符号char型
unsigned char c=-1; //-1是int型,要被转换成无符号的char型
printf("a=%d,b=%d,c=%d",a,b,c); //然后a,b,c再转换成有符号的int型。
return 0;
} //a=-1,b=-1,c=255;
而a和b因为都是有符号的,先隐式类型转换成char类型。最后隐式类型转换回int,这一次转换的时候,也是要补符号位。但因为a和b都是有符号的,符号位是1,所以高位补1,结果就又变回了-1。
2.
#include <stdio.h>
int main() {
char a = 128; //有符号的char类型数据范围为-128~+127,而128超出了它的表示范围,所以会发生溢出。
printf("%u\n",a);// 4294967168
return 0;
}
本题a = 128超出了char表示的数据范围,所以会产生溢出。128可以转换成127+1,结果会发现是-128。然后在高位补符号位1,就变成了11111111111111111111111110000000,这是一个有符号的int类型然后在转换成unsigned int类型。此题不光涉及隐式类型转换,还有数据类型的优先级问题以及数据类型的表示范围。
3. int main() {
char a[1000];
int i;
for(i=0; i<1000; i++) {
a[i] = -1-i;
}
printf("%d",strlen(a)); //strlen求字符数组长度,遇到‘\0’停下来。
return 0;
}
11111111111111111111111111111111
00000000000000000000000011111111
00000000000000000000000000000000
然后高位截断,只保留低八位。即00000000,这个时候a[i] = 0,strlen(a)就会停下来。此时i = 254。长度就是255。
-1 - i如果当成int来理解,不可能为0。但如果当成char类型来理解,就有机会在转换成char的过程中,高位截断。高位是啥都不重要,重要的是让最低八位为0即可。即可构造出一个ascii值为0的字符。当i=255时,会给数组元素设为‘\0’,0-254这样的下标对应的元素就都是字符串的有效元素 ,字符串的长度就是255。