繁体   English   中英

C内存地址和值

C memory address and values

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我有一个问题,我似乎无法弄明白。 我希望有人能够彻底向我解释。 我觉得这很简单......

问题如下:

以下变量如何进入连续的内存地址及其值?

int8_t a = 0x65;
char b = 'k';
uint16_t c = 22222;

例如,

int8_t esim = 9;

将被存储为

0000:00001001

任何人?

2 个回复

我有一个问题,我似乎无法弄明白。 我希望有人能够彻底向我解释。 我认为这是非常基础的。

在这里你出错了。 非常基本的,但并不像你想象的那样

  • 不同的变量不需要存储在内存中的连续位置。 (或者最后一颗子弹说,根本不存储在内存中)

  • 多字节值中的单个字节的存储是实现定义的 - 检查编译器手册。 然而,现在大多数个人计算处理器都使用little-endian 2补码作为整数。

  • 即使他们由编译器组织在内存中出现,正是因为他们的声明相同的顺序,每个数据类型都需要实现特定的排列,因此在它是此对齐的倍数的地址只启动

  • 最后,不需要任何变量或内存分配,编译器只需要生成一个程序, 就好像有这样的变量一样。


不过,我们当然可以说一下您的计划。 如果摘录

#include <stdint.h>

int8_t a = 0x65;
char b = 'k';
uint16_t c = 22222;

编译并将变量放在内存中

  • a将为8位,值为0b01100101
  • c将为16位并作为2个字节存储在存储器中 - 0b110011100b01010110在增加的存储器地址(little-endian,通常),或相同的2个字节反转: 0b010101100b11001110 (big-endian)。
  • 至于b如果 执行字符集是ASCII兼容的,因为int8_t存在,那么char也必须是8位宽,然后它的值将被存储为0b01101011 (即107, k的ASCII码)。

另外,大多数情况下uint16_t对象的对齐要求是2; 如果是这种情况,它必须从偶数地址开始。

这种推论是唯一可能的,因为int8_tuint16_t 不能有填充位 ,因此通过它们我们可以推断出最小可寻址单元( char )的宽度也必须是8位。 并且uint16_t只有2个字节,因此它只能有两个字节序选择。


很容易测试GCC如何组织全局变量 考虑具有源代码的模块

#include <stdint.h>
int8_t a = 0x65;
char b = 'k';
uint16_t c = 22222;

我们可以将它编译成目标文件:

% gcc -c layouttest.c -o layouttest.o

然后使用nm列出符号及其地址:

% nm layouttest.o            
0000000000000000 D a
0000000000000001 D b
0000000000000002 D c

这似乎是Jabberwocky的答案所期望的。 如果我们现在使用-O3编译,结果可能会有所不同:

% gcc -c layouttest.c -o layouttest.o -O3; nm layouttest.o
0000000000000003 D a
0000000000000002 D b
0000000000000000 D c

即变量被重新组织,底部是c

Antti Haapala答案的补充:

虽然完全取决于编译器如何以及在何处存储变量,但连续声明的变量的内存布局通常与声明顺序的顺序相同,尤其是在非优化代码中。

所以变量声明如下:

int8_t a = 0x65;
char b = 'k';
uint16_t c = 22222;

可以像这样存储:

Address  Content in binary
--------------------------
0000:    01010101  (0x64)
0001:    01101011  ('k' = 107, ASCII code of k)
0002:    11001110  (low bits of 22222)
0003:    01010110  (high bits of 22222)

其中Address是相对地址,带有对变量a的内存地址的repsect。

再一次:不要认为这是您平台上必然的情况。

1 C#内存地址值不能修改?

在图片中使用“ OllyDbg”应用程序。 我的问题:为什么不能修改Q1部分图片中的值? (任何地址都不能。) 但是可以在第二部分进行修改吗? 我的C#代码: ...

2 C:内存地址数组?

我正在尝试为多个不同的结构制作一种容器。 不幸的是,C 只允许类型特定的数组,这意味着我必须为每种类型的结构创建一个不同的数组。 我提出的当前解决方案是一个保存内存地址的容器。 这样,程序就可以将其中一个元素的内存地址传递给函数。 目前我唯一的代码是使用 void 指针的失败尝试(不幸的是,我对 ...

2021-06-07 12:48:19 2 83   c
4 C++ 内存地址?

内存地址如何工作? 在 32 位中,内存地址是一个十六进制值,如 0x0F032010,对吗? 但是这些值是指向字节还是位? 以及 0x0F032010 和 0x0F032011 等两个内存地址之间的内容 ...

5 C内存地址问题

如果pta是局部变量的内容(即intarray [0]的地址),那么pta +5是什么意思? 有人可以解释吗? 谢谢 ...

2011-03-08 07:27:25 2 276   c
6 C变量的内存地址

这是我的测验问题(警告,冗长): 给定以下程序,重新排序printf行,以便在Sun SPARC体系结构上编译和运行时,打印的值从最小到最大排序。 这些行使用printf()格式说明符%p(指针)打印出程序不同部分的十六进制地址(不是指定的值)。 我用C运行这个程序并得到这些打印 ...

7 C ++内存地址

如果这是重复的问题,请原谅 这是我的代码 这是输出 Address2是003EFAA4,地址处的值为Hello //我很容易理解 下一个地址2是003EFAA8(这是我很难理解的地方。我的理解是,考虑到char是1字节,下一个地址应该是003EFAA5? ...

8 理解内存地址的值

出于好奇,我编写了一个非常简单的程序来读取单元素数组前后的前 1000 个字节,只是为了看看我会得到什么值,以及如何使用它们。 #include &lt;stdio.h&gt; int main(){ char mem[1]; printf("\n\tSeeking Ahead.. ...

9 显示的是内存地址而不是值?

自Visual Studio Enterprise 2015最初发布以来,我一直在使用它,并且像调试.net应用程序时一样,能够像查看传统一样看到本地成员和字段的价值。 但是今天,我注意到我不再看到这些值,而是相信我看到的是内存地址或十六进制值。 是什么会引起这种变化? 如何将其 ...

10 内存地址输出而不是值

程序输出是: std::vector(0x55f164f79450)而不是Childs[one] :我在这里做错了什么? 任何帮助,将不胜感激 ! 在线示例: http : //www.angusj.com/delphi/clipper/documentation/Docs/Units/Clip ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM