整型不同类型数值的转换一:扩充(将表示范围小的整型变量赋值给表示范围大的整型变量)
方法:若该数本身为有符号数,在其二进制数补码形式最前面扩充符号位;无符号扩充0。补码的形式参与运算!!!
如:char a=5; short x=(short)a; //char类型为有符号、1字节(8 bit),赋值给short短整型2字节(16bit),要进行扩充。a=5=0000 0101,因为有符号数扩充符号位故将a扩充为:0000 0000 0000 0101,由于a为正数,因此该临时值即为最终结果。
再如:char b=-5; int y=(int)b; //char类型为有符号、1字节(8 bit),赋值给int整型4字节(32bit),要进行扩充。b=-5=1000 0101(原码)=1111 1011(补码),有符号数扩充符号位故将其扩充为:1111 1111 1111 1111 1111 1111 1111 1011,由于扩充结果(临时量)为其补码表示形式,故最终结果转为原码为:1000 0000 0000 0000 0000 0000 0000 0101。
分析下面的代码,深入理解扩充:
#include<stdio.h>
int main() {
char c = 128;
unsigned char uc = 128;
unsigned short us = 0;
us = c + uc;
printf("%x\n", us); //第一个 结果为0
us = (unsigned char)c + uc;
printf("%x\n", us); //第二个 结果为100
us = c + (char)uc;
printf("%x\n", us); //第三个 结果为ff00
us = (unsigned short)c + uc;
printf("%x\n", us); //第四个 结果为0
return 0;
}
1.us=c+uc; //c+uc结果赋值给无符号短整型2字节的us,需要进行扩充。
c:有符号char类型,c=128=1000 0000(首位既是符号位也是数值位,-128),有符号数扩充符号位:c=1111 1111 1000 0000
uc:无符号char类型,uc=128=1000 0000(首位仅代表数值位),无符号数扩充0:uc=0000 0000 1000 0000
故c+uc=1111 1111 1000 0000+0000 0000 1000 0000=1 0000 0000 0000 0000,由于短整型为2字节8位,故截取低八位作为结果:0000 0000 0000 0000=0(16进制)
2.us = (unsigned char)c + uc;
c:先强转为无符号char类型,设该无符号char类型临时量(先强转再扩充!)为c’=128=1000 0000(首位仅代表数值位),无符号数扩充0:c‘=0000 0000 1000 0000
uc同1的扩充,uc=0000 0000 1000 0000
故c'+uc=0000 0000 1000 0000+0000 0000 1000 0000=0000 0001 0000 0000=100(16进制)
3.us = c + (char)uc;
c同1的扩充,故c=1111 1111 1000 0000
uc:先强转为有符号char类型uc’=128=1000 0000(首位既是符号位也是数值位,-128),故其扩充符号位后为uc‘=1111 1111 1000 0000
故c+uc’=1111 1111 1000 0000+1111 1111 1000 0000=1 1111 1111 0000 0000,截取低八位为:1111 1111 0000 0000=ff00(16进制表示)
4.us = (unsigned short)c + uc;
c:c为1字节有符号数,要强转为无符号短整型即在强转的时候进行扩充!扩充只取决于自身为有符号或无符号进行扩充!!此处要强转的类型决定扩充为几字节!故c:1000 0000(首位既是符号位也是数值位,-128),强转即扩充为2字节:c‘=1111 1111 1000 0000
uc同1的扩充,uc=0000 0000 1000 0000
故c’+uc=1111 1111 1000 0000+0000 0000 1000 0000=1 0000 0000 0000 0000=0(16进制)