K&R Exercise 2-1
char
a = (unsigned char) ~0;
char b = (unsigned char) ~0 >> 1;
char c = (unsigned char)(~0 >> 1);
unsigned char d = (unsigned char) ~0;
unsigned char e = (unsigned char) ~0 >> 1;
unsigned char f = (unsigned char)(~0 >> 1);
printf("%u\n", x); // x is a, b, c, d, e or f.
a. 2^32-1 截断11111111, printf中char首先转换为int, 符号扩展2^32-1, int再转换为unsigned, 输出2^32-1;
b. 2^32-1 截断11111111, 无符号数逻辑右移01111111, printf中char先转换为int, 再转换为unsigned, 符号位为0, 扩展不变,输出2^7-1;
c. 2^32-1 有符号数算术右移2^32-1, 截断11111111, 余下同a;
d. 2^32-1 截断11111111, printf中unsigned char直接转换为unsigned, 输出2^8-1;
e. 2^32-1 截断11111111, 无符号数逻辑右移01111111, printf中unsigned char直接转换unsigned, 输出2^7-1;
f. 2^32-1 有符号数算术右移2^32-1, 截断11111111, 余下同d.
总结:
1. 算术右移因为截断在输出看不出差异,但是有本质不同;
2. char, short, int, long的signed和unsigned在内存中没有区别;
3. char->short->int->long类型转换时, 如果被转换数为signed型则存在符号扩展问题;
4. signed char首先转换为signed int, 符号扩展, signed int再转换为int;
5. 符号扩展的根本目的在于保证以补码形式保存的signed数在位数增加后其值不变,因此也必然以被转换数的类型作为是否进行符号扩展的标准.
阅读(1845) | 评论(1) | 转发(0) |