程序员C语言中,当不同类型的数据进行运算的时候,就会发生强制或隐式类型转换,通常是低精度的数据类型扩展到高精度的。有些时候,低精度的位数比较少,扩展到高精度的时候,就要在前面补充一些位。那么这些位是补0还是补1呢?这就涉及到无符号扩展和带符号扩展。
0 e3 X/ x0 N$ V 扩展的原则是:1.有符号的数据类型,在向高精度扩展时,总是带符号扩展 * E# A- `, b) K: Q8 O0 j
2.无符号的数据类型,在向高精度扩展时,总是无符号扩展 6 V; j/ Z, `# A, F( ]
怎么理解呢?首先来看一道题目,按此题目讲解完你就明白了!
5 V2 K, ^9 _& X- t# w) X- m charca=128; % l% M: ^% T( N5 h q% ]
unsignedcharucb=128; 8 f0 U2 F m' U5 h, `; W
unsignedshortusc=0;
1 e4 l! l3 p$ L5 ? 1)usc=ca+ucb;
3 K5 r9 c! Q1 [3 `6 a* K printf("%x",usc);
, V) I6 d6 g. H/ x+ Y$ S 2)usc=ca+(unsignedshort)ucb; " B7 q' `1 T" s3 T7 T* i. C
printf("%x",usc); 4 r- Z* C+ [1 p7 q
3)usc=(unsignedchar)ca+ucb;
, D \' j& T3 [5 l printf("%x",usc);
9 g- T6 e* J7 V8 e 4)usc=ca+(char)ucb; 7 p+ _, K0 w) H3 I U5 O8 X8 a% U+ n, T
printf("%x",usc);
1 e) L8 J7 N* z/ w7 z* _1 x n 问,在1、2、3、4这4种情况下分别输出什么? & F5 d# V* _! k- G
分析:
6 I! S9 z2 K* q( C R 1)对于char类型,有符号,128已经溢出了,其二进制是10000000,第一位会被当成符号位,也是就是说此时它是负数了,它扩展成unsignedshort时,带符号位扩展,符号位为1,所以在前方补1,结果是111111111000000.ucb类型为nsignedchar,无符号,二进制是10000000,扩展成unsignedshor,无符号扩展,所以补0,结果是0000000010000000,。相加结果为10000000000000000由于unsignedshort是二字节,舍弃最前面的1,所以得到0x0,
, z/ X1 {3 q$ X7 D! v4 N, e 2)情况和1一样,只是将ucb显示强制转换为unsignedshort,所以得到0x0, 5 h$ I, h& P9 W2 w
3)ca先强制转换为unsignedchar,仍然是10000000,注意此时转换后已经是一个无符号数,所以再往unsignedshort扩展时,为无符号扩展,结果为0000000010000000,ucb扩展后
' f$ S8 Y* t0 T- x4 i 也是0000000010000000,相加结果为0000000100000000,所以结果为0x100 4)ca转为unsignedshort,带符号扩展,为111111111000000,ucb先强制转换为char,然后再转为unsignedshort,此时也要带符号扩展,所以也是111111111000000,两数相加,得到11111111100000000,所以结果为0xff00 |