我们在该文中分析了uchar/char的范围及越限情况。
期间有个现象在这里分析以下:
我们发现,uchar以十六进制的形式输出是FF,但是char类型以十六进制输出的是ff ff ff ff
uchar ch1 = 0xFF;
char ch2 = 0xFF;
printf("%d,%d\n%X,%x\n",ch1,ch2,ch1,ch2);
printf("%d",sizeof(int));
分析:编译器是32位的,所以是 ff ff ff ff,共32位, 4个字节。又因为,对于char类型,ff(1111 1111),首位是1,故为负数,所以,拓展成4个字节后,前面全是1
补符号位原则:
如果数据类型为有符号的(比如char类型),且数据最高位是1,则转换成多字节数时,高位全都补1,即十六进制数都是F。
包括数据为负数时,比如 int = -32768;
如果数据类型为无符号的(比如uchar类型)高位全都补0,即十六进制数都是0,默认是不写的。
此外,char与多字节的位运算(即,强转成多字节时),以及如下的位移运算也算牵扯到补符号位的问题。
数据存储在计算机中的是二进制,如果是正数存的是原码(也可以理解为补码,因为正数的原码和补码相同),如果是负数存的是补码,归纳为,
1)数据存在计算机的都是补码;
2)整型为十六进制数,则表示的就是补码;//char ch = 0xaa;
3)整型数据为十进制数,则需要先转换成二进制补码的形式(十六进制);
4)同一个数存储在相同位数的数据类型中,其存储的二进制(十六进制)是完全一样的,不会发生丢位,最终转换为十进制数,或者扩展为多字节数是多少,是由我们要解析的形式决定的。
// char ch1=-1; uchar ch2 = -1; 二者存储的二进制都是 FF;
//printf("%x,%x",ch1,ch2);//输出的是FF FF FF FF; FF
5)数据转换过程: uchar ch =-1; printf("%x,%d,%u",ch,ch,ch);
- 在32位机上编译: -1默认的是int型,转换为二进制:FF FF FF FF
- uchar位一个字节,故截取低八位,为FF;
- 按照补符号位原则,根据%x,%d,%u的规则,解析输出;
举例:
//十进制数显示问题
uchar ch1 =-1;
printf("%x,%d,%u\n",ch1,ch1,ch1);
char ch2 =-1;
printf("%x,%d,%u\n",ch2,ch2,ch2);
printf("*****************\n");
//十六进制数显示问题
uchar ch3 =0xAA;
printf("%x,%d,%u\n",ch3,ch3,ch3);
char ch4 =0xAA;
printf("%x,%d,%u\n",ch4,ch4,ch4);
printf("*****************\n");
//数据类型强转后数据显示问题
uchar ch5 = -1;
printf("%x,%d,%u\n",ch5,ch5,ch5);
char ch6 = -1;
printf("%x,%d,%u\n",(uchar)ch6,(uchar)ch6,(uchar)ch6);
printf("*****************\n");
//不同数据类型相互赋值后的显示问题
uchar ch7 = -1;
char ch8 = -1;
char ch9 = ch7;
uchar ch10 = ch8;
int ch11 = ch7; //短字节扩展为长字节需要补符号位
uint ch12= ch7; //短字节扩展为长字节需要补符号位
int ch13= ch8; //短字节扩展为长字节需要补符号位
uint ch14 = ch8; //短字节扩展为长字节需要补符号位
printf("%x,%d,%u\n",ch7,ch7,ch7);
printf("%x,%d,%u\n",ch8,ch8,ch8);
printf("%x,%d,%u\n",ch9,ch9,ch9);
printf("%x,%d,%u\n",ch10,ch10,ch10);
printf("%x,%d,%u\n",ch11,ch11,ch11);
printf("%x,%d,%u\n",ch12,ch12,ch12);
printf("%x,%d,%u\n",ch13,ch13,ch13);
printf("%x,%d,%u\n",ch14,ch14,ch14);
short si = -32768;
unsigned short usi=si;
int i = si;
unsigned int ui=usi;
unsigned int ui2=-32768;
unsigned int ui3=0xAA;
printf("short: decimal:%d Hexadecimal:%x\n",si,si);
printf("unsigned short: decimal:%d Hexadecimal:%x\n",usi,usi);
printf("int: decimal:%d Hexadecimal:%x\n",i,i);
printf("unsigned int: decimal:%d Hexadecimal:%x\n",ui,ui);
printf("unsigned int: decimal:%d Hexadecimal:%x\n",ui2,ui2);
printf("unsigned int: decimal:%d Hexadecimal:%x\n",ui3,ui3);
short svalue= -32769;
printf("%d,%x\n",svalue,svalue);