笔试常见之C类型转换
腾讯实习笔试遇到C类型转换的基础问题,题目及分析如下:
32位的机器下,下面说法哪些是正确的?
signed char a = 0xe0;
unsigned int b = a;
unsigned char c = a;
A. a>0 && c>0 B. a==c C. b的十六进制的表示是:0xffffffe0 D. 以上说法都是错误的
解析:
A错,signed char比较时候类型要提升成int,符号位是补最高位的1,所以a应该是负数
B错:a和c都要要先转换成int类型才进行比较,a转换成int后是负数,c转化成int之后是正数
C对:signed char先转化成int类型再转化成unsigned int类型,signed char转化成int时候要进行符号扩展,因为是有符号类型,所以最高位就是补1.
这一类题目在笔试面试中很常见,但很容易出错,下面对这一类数据类型转换进行深入详说:
一.C/C++中常见数据类型的大小、范围如下图(32位机器下):
二.类型转换引发的学问
在32位机器中,各种数据类型的长度范围基本是不一样的,当两个不同长度或者相同长度的数据类型进行转换时,会发生各种不同的值变化。
1.char转为为int类型,即有符号signed char转换为signed int:
char类型占1字节内存大小,int类型占4字节,所以char转为int,在int类型变量高位前3个字节要填充,填充位的二进制为char类型最高位的比特,如
char a=0x11;// 0001 0001(1字节)
int b=a;//前3字节补0
转化后b的十六进制为0x00000011
若有
char a=0x81;// 1000 0001
int b=a;//前三个字节补1
转化后b的十六进制为0xffffff81
2.unsigned char转为int又是不同的,
如:
unsigned char a=0xf1;//或a=0x11;(最高位是1或0的差别)
int b=a;
printf("%x\n",b);
这里无论无符号char类型变量的最高比特是0或1,转为有符号int类型时,int前面高三位字节都是补0
总结:字符类型转换为int类型,如果是signed char转换为大字节类型时,大字节类型的前面部分字节比特填充的是char类型变量的符号位,若是unsigned char类型转换为大字节类型时,高字节部分填充0。
3.Int转为long类型时,由于int和long都是4字节,所以无需填充。
4.Int类型转为long long类型时,是4字节转换为8字节,低字节转高字节,需要填充位。由于int是带符号位整型,所以转换需填充符号位
1 #include<stdio.h> 2 int main() 3 { 4 unsigned char a=0xff; 5 long b=a;//long可替换为int,结果一样 6 printf("%x\n",b);//输出ff 7 8 //int->long long 带符号,填充符号位 9 int a1=0x81223456; 10 long long b1=a1; 11 printf("%llx\n",b1);//输出ffffffff81223456 12 13 //uint (无符号)转为long long ,填充0 14 unsigned int a2=0x82345678; 15 long long b2=a2; 16 printf("%llx\n",b2);//输出 82345678(十六进制,已省略前面有8个0) 17 18 int a3=0x81123456; 19 unsigned int b3=a3; 20 printf("%x\n",b3);//输出的结果同a3,但b3是无符号,输出的是无符号数 21 printf("%d %u",a3,b3);//a3带负号,b3为无符号 22 }