首页 > 解决方案 > c语言如何在内存中存储int?

问题描述

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p_x = (int *)malloc(1 * sizeof(int));
    scanf("%d", p_x);

    for (int i = 0; i < 4; i++) {
        char *one_byte_slice = (((char *)(p_x)) + i);
        printf("slice : %d , value : %d\n", i, *one_byte_slice);
    }
    return 0;
}

当我输入正值时,它们对我来说似乎可以理解,但对于负值,我不太理解。

对于*p_x = 127

127
slice : 0 , value : 127
slice : 1 , value : 0
slice : 2 , value : 0
slice : 3 , value : 0

p_x  --->  0111 1111
           0000 0000
           0000 0000
           0000 0000

对于*p_x = 256

256
slice : 0 , value : 0
slice : 1 , value : 1
slice : 2 , value : 0
slice : 3 , value : 0

p_x  --->  0000 0000
           0000 0001
           0000 0000
           0000 0000

对于*p_x = -20

-20
slice : 0 , value : -20
slice : 1 , value : -1
slice : 2 , value : -1
slice : 3 , value : -1

p_x  --->  1001 0100
           1000 0001
           1000 0001
           1000 0001

对于*p_x = -256

-256
slice : 0 , value : 0
slice : 1 , value : -1
slice : 2 , value : -1
slice : 3 , value : -1

p_x  --->  0000 0000
           1000 0001
           1000 0001
           1000 0001

那么它是如何存储在内存中的定点数是以2的补码或其他方式存储的呢?

标签: cpointersmemorybytebit

解决方案


这称为低端编码。整数的各个位片从最低有效到最高有效存储在连续字节单元中。您的整数以二进制形式表示为:

0000 0000 0000 0000 0000 0000 0111 1111

(我使用了一个空格来分隔每组四位)。每个字节从最不重要的八位组存储到最多,在增长的字节地址中,从右上方开始:

Addr.  Value.
0000: 0111 1111
0001: 0000 0000
0002: 0000 0000
0003: 0000 0000

还有另一种方法,称为 big-endian,它以相反的方向存储字节,有些机器会这样做:

(Big-endian)
Addr.  Value.
0000: 0000 0000
0001: 0000 0000
0002: 0000 0000
0003: 0111 1111

还有其他方法可以做,但今天的计算机通常使用这两种方法之一。

在负数的情况下,解决方案在于认为负数和正数是这样的,因此可以在不必使用备用电路的情况下进行加减运算。所以数字被分成两半,最高有效位的代表负数……所以数字被表示(为了简洁起见,我只使用四位):

1000: -8
1001: -7
1010: -6
1011: -5
1100: -4
1101: -3
1110: -2
1111: -1
0000: 0
0001: 1
0010: 2
0011: 3
0100: 4
0101: 5
0110: 6
0111: 7

使用 32 位结果是相同的,但扩展到 32 位......这使得所有小的负数的所有最高有效位都等于1.

1000 0000 0000 0000: -2147483648
1000 0000 0000 0001: -2147483647
...
1111 1111 1111 1101: -3
1111 1111 1111 1110: -2
1111 1111 1111 1111: -1
0000 0000 0000 0000: 0
0000 0000 0000 0001: 1
...
0111 1111 1111 1100: 2147483644
0111 1111 1111 1101: 2147483645
0111 1111 1111 1110: 2147483646
0111 1111 1111 1111: 2147483647

以这样一种方式,加法在上一个表中向下跳跃,而减去向上。这称为二进制补码编码。


推荐阅读