1、
#include <stdio>h>
int main()
{
char a=-1;
signed char b=-1;
unsigned char c=-1;
printf("%d %d %d",a,,b,c);
return 0;
}
运行结果为:-1 -1 255
为什么了?
我们知道数据在内存中,是以补码的形式储存的,
分析a:-1是一个四字节的整型,它的原码:10000000 00000000 00000000 00000001 ,
他的补码:11111111 11111111 11111111 11111111;
要把它赋值给一个一字节的char型,我们需要对-1的补码进行截断,因此,a的补码:11111111
接下来,我们要把这个char型a输出,我们可以看到,代码要求我们以‘%d’输出,就是要求我们以(signed int),这个数据类型输出,因此,我们需要对a进行整型提升,提升后的补码:11111111 11111111 11111111 11111111,记住输出的是原码,a提升后的原码:1000000 0000000 00000000 00000001,因此输出的结果为-1
同理,b的结果也是-1
补充,在C语言中,规定int 为(signed) int,但是没有规定char 为(signed) char,这要取决于编译器,
接下来,我们分析c的结果为什么会是255,
根据前面,我们可以知道,c的补码为11111111,整型提升后的补码(向左补0,因为c为无符号):0000000 0000000 00000000 11111111,无符号数据原、反、补相同,所以,输出结果为255,
2、
#include <stdio.h>
int main()
{
char a=128;
char b=-128;
printf("%u %u\n",a,b);
return 0;
}
输出结果为 4294967168 4294967168
a的补码:10000000 ,整型提升后的补码:11111111 11111111 11111111 10000000
因为,输出是要求以‘%u’以无符号整型输出,所以补码最左边的1由原本的符号位变为有效数位,所以结果为4294967168
b的补码:100000000,整型提升后的补码:11111111 11111111 11111111 10000000吗,
同理,输出结果也为4294967168
补充:原本输出是补码要变为原码再输出的,但是要以无符号输出,相当于是一个正整数,所以整型提升后原、反、补相同,
3、
#include <stdio.h>
int main()
{
int i=-20;
unsigned int j=-10;
printf("%d\n",i+j);
if(i+j>0)
printf("yes\n");
else
printf("no\n");
return 0;
}
运行结果:-30 yes
i的原码:10000000 00000000 00000000 00010100,i的补码;11111111 11111111 11111111 11101100,
j的原码:10000000 00000000 00000000 00001010,j的补码:11111111 11111111 11111111 11110110,
i+j的补码:11111111 11111111 11111111 11100010,以无符号的整型输出,i+j的原码为100000000 00000000 00000000 00011110,所以输出结果为-30,
那有人就会疑惑,为什么输出结果是负数,为什么还会输出yes,下面就要我们来探讨一下。
我们知道i+j是 一个无符号的整型+一个有符号的整型,这是会进行隐式转换(由精度低,范围小的类型向精度高,范围大的类型转换),因此,我们i+j就是一个unsigned int 的数据,所以它一定是大于0的,
那为什么会输出-30呢?这是因为,i+j要以“%d”输出,也就是说,要以有符号的整型的数据类型输出。