首先要知道我们的数据是怎么样放入内存的,例如我们int a=2;sizeof(int)=2;那么放入内存的数据为00000000 00000010,假设int a=-2,那么存放为11111111 11111110,始终记住在内存里存放的是补码形式,正数的补码是本身。现在要用printf输出,就先要到内存里面去得到数,假设%d形式输出,则函数根据符号为进行求源码,如果是%u输出则函数认为内存里存放的为无符号数,所以直接输出数字11111111 11111110=65534。
假设我们把一个int赋给char的,那么int 就要被截断了,底8位不动的直接挪给char,例如unsigned char c;
C=a;那么c对应的内存为11111110(当a=-2),当我们输出格式为%d,%u的时候都是254哦,这和unsigned int a=-2不一样,当我们输出格式为%d,%u的时候一个正数,一个负数。
假设我们相反把一个char赋给int,那么就要进行符号扩展了,谭书上60页说了:
如果把字符处理为无符号的,那么int的高位全部补0;
如果把字符处理为有符号的,那么int的高位与char放在内存的数据的最高为扩展,例如char c=-2,在内存里面格式为11111110,那么int a=c,a的格式为11111111 11111110,如果char c=2,在内存的存放为00000010,那么int a=c,a的格式为00000000 00000010
记住printf的格式控制是从内存里面取数据,在进行相应的转换的
2
当我们输入数据的时候假设int a=2,那么内存里面高位扩0,但是如果int a=65535,那么16为已经满了它不会写成0 11111111 11111111因为这样已经17位了
一个符号扩展的例子:
typedef struct {
int a:2; 1
int b:2; 2
int c:1; 3
}test;
test t;
t.a = 1; 4
t.b = 3; 5
t.c = 1; 6
printf(“%d”,t.a); 7
printf(“%d”,t.b); 8
printf(“%d”,t.c); 9
谢谢!
t.a为01,输出就是1
t.b为11,输出就是-1
t.c为1,输出也是-1
—位扩展
解释:a不说,对于b来说,t.b=3,写进内存为11,因为已经满2位了,所以直接进驻内存,不用扩展符号,(不考虑补码的形式),但printf输出的是int型,所以要进行到2到16位的扩展,因为申明的是int
b:2;所以高16位字节与b的最高位一样为111111111 11111111,所以输出为%d的形式输出为-1,如果%u的形式,那么输出为65535.
假设我们在第2行中把int b:2,写成unsigned int b:2,那么结果就变了哦,这就导致了进行符号扩展的时候全部补0,结果是在内存的格式就是00000000 00000011输出的两种都为3.
具体的符号扩展应该具体分析,有错误的地方指出哈!本人还是菜鸟
>> 本文固定链接: http://www.vcgood.com/archives/3129
>> 转载请注明: diantouxiao 2009年04月02日 于 C语言帝国 发表
最进发现一个嵌入式工程师网站,竟然还有招聘信息
网址:http://chengdu.akaedu.org