char类型和short,int类型之类的转换

                    char类型和short,int类型之类的转换


今天偶遇一个printf输出小问题,代码如下:


#include
#include
using namespace std;
int main()
{
 chara=0xff;
 printf("%x",a&0xffff);
 system("pause");
 return 0;
}
输出:ffff



char类型和short,int类型之类的转换_第1张图片

初次分析如下:以为char只有一个字节,所以& short之后,补上前面的一个字节ff,所以为ffff.

 

但换成 char a=0x0f  ,输出的是f。


char类型和short,int类型之类的转换_第2张图片


而换成 unsigned char 如下:
#include
#include
using namespace std;
int main()
{
 unsigned char a=0xff;
 printf("%x",a&0xffff);
 system("pause");
 return 0;
}
输出:ff

char类型和short,int类型之类的转换_第3张图片

 

分析:直到尝试无符号字符型,才想起来数据的范围,char的范围是-128~127,而unsigned char的范围是0~255. 所以在做  char  & short(int) 操作或者直接使用printf(“%x”,a)时,会自动补位。printf(“%x”,a)可以输出指定参数的16进制形式,但是在实际的使用中,参数不一定都是32位的整数,有可能是16位的short,8位的char。所以它们在输出%x时,会自动补位。而补位的规则就是补符号位,因为char 最大的正值为7f(127),超过就会溢出,变成负数,符号位为1,所以前面补ffffff(变成int ),而7f 前面符号位是0 ,所以补24个0之后,输出7f。验证下:

 char类型和short,int类型之类的转换_第4张图片


char类型和short,int类型之类的转换_第5张图片


所以char 转换成short ,int 都是同理,而short 转换成int 时也是同理,补符号位,验证如下:

char类型和short,int类型之类的转换_第6张图片

char类型和short,int类型之类的转换_第7张图片

 

所以在数据类型转换时,一定要考虑数据范围,以及有无符号

总结: 短字节的类型 转换成  长字节的类型时, 高位自动补齐 符号位(全0 或者全1)。而 长字节 转换成 低字节时,从低字节开始取。char 的底层存储是 整形的,所以 unsigned char 可以做byte (0`255)使用

另外 移位运算也是补符号位,例如 1<<31>>31, 最后会编成 ffffffff,因为1<<31.是80FFFFFF,所以右移时,高位也是自动补了符号位1,而不是想当然的补0;而左移位自动低位补0。

这里还要注意的是 : 比如int a=oxffff,这里其实符号位还是0的,但如果short a=oxffff,那符号位就是1了。

你可能感兴趣的:(C/C++)