c语言变量存储的本质

1、给定的值若是带(-符号),需将负数转为补码形式。若给定的数无符号表示(即无+-号,即为补码)

     负数补码方法:除符号位外其余位取反(反码),再加1(反码+1)。

      (char) -1 二进制存储格式,变换如下:1000,0001->反码:1111,1110->补码:1111,1111 = 0xff

      所以char a = -1;和char a = 0xff在计算机内的存储是一致的。


2、符号位的扩展

      即一种类型来表示另一种类型(两种不同长度的表示),结果值不变。

      对于无符号整型数据,要扩展成符号位的话,就是将扩展位补零,其他位保持不变。

      对于有符号整型数据的符号扩展规律就是:其他位保持不变  原来符号位为1时,符号扩展位补1;原来符号位为0时,符号扩展位补0;


int a;

char b;

b = -1;

a = b;

b在内存存储值:1111,1111 = 0xff。这里用b给a赋值,不同类型赋值涉及类型变换,考虑符号位的扩展。增加的位补符号位,所以a的存储:1111,1111,1111,1111,1111,1111,1111,1111 = 0xffffffff,表示为int 类型的-1,值不变

int main()  
{  
    char k = 0xff;//k的存储区1111,1111
    char c = -1;//-1在给c赋值时,将机器码(补码)1111 1111 赋值给c的存储区,故c的存储区为1111 1111  
    unsigned char ch = -1;//-1给ch赋值时,ch存储区为1111 1111  
    int a = c;// 用c给a赋值时,是将1111 1111拓展到32位存储区,有关符号,故a的存储区是1111 1111 1111 1111 1111 1111 1111 1111  
    int b = ch;//用ch给b复制时,是将1111 1111拓展到32位存储区,无关符号,故b的存储区是0000 0000 0000 0000 0000 0000 1111 1111  
    unsigned m = c;//用c给a赋值时,是将1111 1111拓展到32位存储区,有关符号,故a的存储区是1111 1111 1111 1111 1111 1111 1111 1111  
    unsigned n = ch;//用ch给n复制时,是将1111 1111拓展到32位存储区,无关符号,故a的存储区是0000 0000 0000 0000 0000 0000 1111 1111  
    //由此看出,给某一类型变量赋值常量时,是把常量的补码按照有符号拓展到该类型变量的存储区的  
    //由此看出,不同类型变量赋值拓展时,是有符号拓展还是无符号拓展,和被拓展数有无符号位有关  
    printf("k=%d,k=%u,a=%d  b=%d  m=%u  n=%u",k,k, a, b, m, n);//结果k=-1,k=4294967295  a=-1  b=255  m=4294967295  n=255  
    //k=%d,=%u需将k分别扩展32,扩展位带符号,固printf临时存储0xffffffff
    return 0;  
}  




猜你喜欢

转载自blog.csdn.net/xmzzy2012/article/details/78940312