C语言存储 低位在前,高位在后

先来看一个奇怪的问题

#include<stdio.h>
union test
{
    int k;
    char c[2];
}a;
int main()
{
    a.k=-7;
    printf("%d,%d",a.c[0],a.c[1]);
}

再说一下存储编码

  • C 语言在内存中存储数据是使用补码

现在再猜猜看之前程序的输出结果是什么?

我们来先自己算一算

int 在内存中占 4 个字节

-7的源码也就是 10000000 00000000 00000000 00000111

那么补码就是符号位不变,其余按位取反+1

  • 即-7 在内存中为: 11111111 11111111 11111111 1111111001

现在再看看结果

weijia$ gcc uniontest.c       
weijia$ ./a.out
-7,-1

为什么是-7 和-1,而不是 -1 和 -1 呢?

其实在内存中(vs和gcc实测)存储是:低位在前,高位在后

内存如下

地址
0x00: 1 1 1 1 1 0 0 1
0x01: 1 1 1 1 1 1 1 1
0x02: 1 1 1 1 1 1 1 1
0x03: 1 1 1 1 1 1 1 1
读取的时候地址为:
0x03 0x02 0x01 0x00

这就应该明白为什么结果是 -7 和 -1 了吧

再来看一个例子验证一下

#include<stdio.h>
int main()
{
    int a=-7;
    char *c=(char*)&a;
    printf("%d,%d,%d,%d ",c[0],c[1],c[2],c[3]);
    return 0;
}
weijia$ gcc inttest.c
weijia$ ./a.out
-7,-1,-1,-1

这样结果是不是就对了,我们将其中的a=-7换成 a=257 试试
因为 257 = 2^8+1
也就是往上一个字节进位,当前字节变成了1
再来看看结果

1,1,0,0

现在的结果是不是跟自己想的一样了?

发表评论

电子邮件地址不会被公开。 必填项已用*标注