c语言中单字节数据转换为多字节数据需要补符号位

我们在该文中分析了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与多字节的位运算(即,强转成多字节时),以及如下的位移运算也算牵扯到补符号位的问题。

扫描二维码关注公众号,回复: 12628200 查看本文章

数据存储在计算机中的是二进制,如果是正数存的是原码(也可以理解为补码,因为正数的原码和补码相同),如果是负数存的是补码,归纳为,

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);

猜你喜欢

转载自blog.csdn.net/modi000/article/details/113520144