char/uchar类型越限总结

我们在文章一文章二中分析了char和uchar的取值范围和越限的情况。

总结:

1、char/uchar本质是保存的整型数,一个字节的整型数;//所谓的字符型,其实是将整型作为ascii码转换成的字符。

2、uchar的取值范围

  • 十进制:0至255
  • 十六进制:0至FF

3、char的取值范围

  • 十进制:-128至127
  • 十六进制:80至7F

4、char/uchar类型越限:

口诀:高减低加(加减256,类似十进制数的加减10,即:加减循环周期)

  • 十进制:当数据高于最大上限,则减256;当数据低于最小下限,则加256;

例如:

    char ch1 = 129;//129-256=-127;

    char ch2 = -130;//-130+256=126;

    uchar ch3=257;//257-256 =1;

    uchar ch4 = -2;//-2+256= 254;
    printf("%d,%d,%d,%d",ch1,ch2,ch3,ch4);

思路:32位编译器:

思路一:129-----》补码:0000 0000 0000 0000 0000 0000 1000 0001---->截取后8位1000 0001,因为是char类型,最高位是1,扩展为%d,符号位补1,1111 1111 1111 1111 1111 1111 1000 0001-》

转换为源码:1000 0000 0000 0000 0000 0000 0111 1111   ----》-127

思路二:129 = 127+2 -----》参考下图,最大的数127,顺移2个位置是-127;

思路一:-130---》补码:1111 1111 1111 1111 1111 1111 0111 1110-----》截取后8位 0111 1110,最高位为0,则使用%d(及扩展为4字节的int)显示: 0000 0000 0000 0000 0000 0000 0111 1110---》126

思路二:-130= -128-2---》参考上图,最小数,逆移2个位置为126;

思路一:257---》补码:0000 0000 0000 0000 0000 0001 0000 0001----》截取后8位:0000 0001,因为位uchar,扩展为%d,0000 0000 0000 0000 0000 0000 0000 0001---->1

思路二:257=255+2---》最大数,255顺移两个位置得1(uchar范围从0-255)

思路一:-2----->补码:1111 1111 1111 1111 1111 1111 1111 1110-------》截取后8位:1111 1110,因为是uchar,扩展为%d,符号位补0,所以是254

思路二:-2=0-2--------》顺移2个位置是254

  • char的十六进制数越限(看成十进制数,char是越限了,但其实该十六进制数在80-7F之间的(1000 0000------0111 1111,这是256个数,包含了以0开头和以1开头的所有的数),并未越限
    uchar ch1 = 0xAA;

    char ch2 = 0xAA;

    printf("%d,%d\n%x,%x",ch1,ch2,ch1,ch2);

 

同样的十六进制数(也就是二进制数1010 1010),将其赋给uchar类型是170,赋给char类型是-86;无论是赋给什么值,十六进制数本身是不变的。

ps:

1)我们发现,将uchar 0xAA和char 0xAA 以十六进制形式打印出来的时候,是有区别的,原因是:

uchar, 0xAA是一个正数,相当于前面都是0,故是0xAA;

char,0xAA(10101010,其实这个数也没有越限,因为首位是1,所以是个负数,因为是在32位机上打印出来的整型占4个字节,所以,拓展为32位,前面都是F),这其实是一个短字节数转换成长字节数的问题。

2)char ch2=0xAA;以%d的形式,即以十进制形式打印出来的话,最终是多少就要将十六进制转换成十进制,然后按照“高减低加”的方式算出最多是多少。

3)对于uchar/char,如果是以一个字节的十六进制数赋值的话,我们赋值是多少,以十六进制输出就是多少(%x,无符号十六进制打印,十六进制不同于十进制的正负号%d/%u,只有无符号。),对于char/uchar,如果赋值的是一个8位的十六进制数,是不存在越限的。

所以,我们习惯于使用char/uchar来存储十六进制数,因为所见即所得。

4)对于uchar/char,我们以一个字节的十六进制数赋值,直接算的话是源码。

5)uchar的范围是从0至255共256个数,char的范围是从80至7F共256个数,相较与uchar,从80至FF从原先表示正数,现在用来表示负数。

5、当uchar/char数据为十进制数时,以十六进制形式输出的是补码形式。(当uchar/char数据为十六进制数时,以十六进制形式原样输出。)

    char ch1 = 129;//129-256=-127;
    char ch2 = -130;//-130+256=126;
    uchar ch3=257;//257-256 =1;
    uchar ch4 = -2;//-2+256= 254;
    printf("%d,%d,%d,%d\n",ch1,ch2,ch3,ch4);
    printf("%x,%x,%x,%x\n",ch1,ch2,ch3,ch4);

    char ch5 = -127;
    char ch6 = 126;
    uchar ch7=1;
    uchar ch8 = 254;
    printf("%d,%d,%d,%d\n",ch5,ch6,ch7,ch8);
    printf("%x,%x,%x,%x\n",ch5,ch6,ch7,ch8);

总总结:

1)十进制数,以十进制形式输出,“高减低加”;

2)十进制数,以十六进制形式输出,先“高减低加”,然后,转换成补码输出;

3)十六进制数,以十进制形式输出,转换成十进制数,“高减低加”输出;

4)十六进制数,以十六进制形式输出,原样输出,注意符号补位。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值