2009
04-02

 

    首先要知道我们的数据是怎么样放入内存的,例如我们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.a01,输出就是1

t.b11,输出就是-1

t.c1,输出也是-1  
位扩展

解释:a不说,对于b来说,t.b=3,写进内存为11,因为已经满2位了,所以直接进驻内存,不用扩展符号,(不考虑补码的形式),但printf输出的是int型,所以要进行到216位的扩展,因为申明的是int
b:2;
所以高16位字节与b的最高位一样为111111111 11111111,所以输出为%d的形式输出为-1,如果%u的形式,那么输出为65535.

假设我们在第2行中把int b:2,写成unsigned int b:2,那么结果就变了哦,这就导致了进行符号扩展的时候全部补0,结果是在内存的格式就是00000000 00000011输出的两种都为3.

    具体的符号扩展应该具体分析,有错误的地方指出哈!本人还是菜鸟


位扩展详解》有 2 条评论

  1. reer123 说:

    最进发现一个嵌入式工程师网站,竟然还有招聘信息

留下一个回复