c中的整数如何存储在内存中?
我认为C中的INT首先以最高有效位存储,例如,数字c中的整数如何存储在内存中?,c,memory,C,Memory,我认为C中的INT首先以最高有效位存储,例如,数字5将是0…0101。我想我可以通过强制C让我假装一个特定的内存地址是一个int,然后像一个int那样添加到位中来操纵特定的位 我尝试在内存中设置0位0,然后尝试将255添加到不同的内存地址,这似乎就像最低有效位存储在内存中的最高有效位之前一样,因为当我在内存地址中添加1并更改位时,我得到的是一个较大的数字,而不是较小的数字。如果最高有效位较早地存储在内存中,则将255添加到内存地址上1字节以上不会影响原始地址的数字,因为最后8位是下一个int的开
5
将是0…0101
。我想我可以通过强制C让我假装一个特定的内存地址是一个int
,然后像一个int
那样添加到位中来操纵特定的位
我尝试在内存中设置0位0,然后尝试将255
添加到不同的内存地址,这似乎就像最低有效位存储在内存中的最高有效位之前一样,因为当我在内存地址中添加1并更改位时,我得到的是一个较大的数字,而不是较小的数字。如果最高有效位较早地存储在内存中,则将255
添加到内存地址上1字节以上不会影响原始地址的数字,因为最后8位是下一个int
的开始。我想知道我是否正确地解释了这一点,INT是以最低有效位存储的
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
int main() {
int *x = malloc(8); //getting 4 memory addresses
int *y = malloc(8);
int *z = malloc(8);
int *a = malloc(8);
x[0] = 0; //setting 64 bits past memory addresses to 0s
x[1] = 0;
y[0] = 0;
y[1] = 0;
z[0] = 0;
z[1] = 0;
a[0] = 0;
a[1] = 0;
*((int*)((int)x)) = 255; //adding to x's memory address
*((int*)((int)y + 1)) = 255; //adding 1 byte over from y
*((int*)((int)z + 2)) = 255; //adding 2 bytes over from z
*((int*)((int)a + 3)) = 255; //adding 3 bytes over from a
printf("%d\n", sizeof(int));
printf("%d,%d\n", x[0], x[1]);
printf("%d,%d\n", y[0], y[1]);
printf("%d,%d\n", z[0], z[1]);
printf("%d,%d\n", a[0], a[1]);
printf("%d\n", x);
printf("%d\n", &x[1]);
return 0;
}
预期产出:
4
255,0
0,-16777216
0,16711680
0,65280
12784560
12784564
实际产量:
4
255,0
65280,0
16711680,0
-16777216,0
12784560
12784564
我认为c中的INT首先以最高有效位存储,例如,数字5将是0…0101
不,这取决于您的平台和工具链,而不是C
您描述的方案(几乎)称为big-endian
现在很多商品PC都是这样,所以正好相反(最低有效字节优先)。你可能就是这样
请注意,endianness谈论的是字节,而不是位
最好不要试图像这样操纵数据。使用该语言,使用不关心尾数的逻辑运算。代码中存在一些问题:
- 位和字节之间似乎有些混淆。计算机内存可寻址为字节,在当前架构中通常由8位组成
- 您不应该将指针强制转换为
,int
可能没有足够的范围来容纳指针的值。将指针转换为int
以修补单个字节,但请注意,由于别名规则,这可能不会产生预期的结果:unsigned char*
((unsigned char *)x)[0] = 255; //adding to x's memory address ((unsigned char *)y)[1] = 255; //adding 1 byte over from y ((unsigned char *)z)[2] = 255; //adding 2 bytes over from z ((unsigned char *)a)[3] = 255; //adding 3 bytes over from a
- 同样,您应该使用
打印%zu
或将大小\u t
转换为大小\u t
int
- 指针应转换为
,并使用(void*)
打印%p
- 如果以十六进制打印
值,更改的效果会更明显int
#包括
#包括
int main(){
//获取4个内存地址,每个地址都有足够的空间容纳2 int,初始化为0
int*x=calloc(2,sizeof(int));
int*y=calloc(2,sizeof(int));
int*z=calloc(2,sizeof(int));
int*a=calloc(2,sizeof(int));
((无符号字符*)x)[0]=255;//添加到x的内存地址
((unsigned char*)y)[1]=255;//在y上加1字节
((unsigned char*)z)[2]=255;//在z上添加2个字节
((unsigned char*)a)[3]=255;//从
printf(“%d\n”,(int)sizeof(int));
printf(“%08x,%08x--%d,%d\n”,x[0],x[1],x[0],x[1]);
printf(“%08x,%08x--%d,%d\n”,y[0],y[1],y[0],y[1]);
printf(“%08x,%08x--%d,%d\n”,z[0],z[1],z[0],z[1]);
printf(“%08x,%08x--%d,%d\n”,a[0],a[1],a[0],a[1]);
printf(“%p\n”,(void*)x);
printf(“%p\n”,(void*)&x[1]);
返回0;
}
输出:
4
000000ff,00000000 -- 255,0
0000ff00,00000000 -- 65280,0
00ff0000,00000000 -- 16711680,0
ff000000,00000000 -- -16777216,0
0x7fd42ec02630
0x7fd42ec02634
4.
000000ff,00000000--255,0
0000FF0000000000--65280,0
00FF000000000000--16711680,0
FF00000000000000--16777216,0
0x7fd42ec02630
0x7fd42ec02634
从上述输出中,我们可以看到:
- 类型
有4个字节int
- 指针使用8个字节(我的环境是64位的,与您的不同)
首先以最低有效字节存储,与您的相同,这被称为小端结构int
- 系统编程、低级编程、设备驱动程序开发、
- 图像处理
- 读取和写入二进制文件和流
- 处理二进制数据的网络传输,尤其是与不同设备之间的传输
- 与其他编程语言接口、编写库等