【问题标题】:How are variables tied to their values in C?变量如何与它们在 C 中的值相关联?
【发布时间】:2018-09-02 06:16:41
【问题描述】:

如果你有这样一行代码

int num = 4;

这会导致以下表格吗?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4

如果你要那么说

int* num_p = #

这会导致以下表格吗?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4
num_p   |0002      0002   |0001

然后会说

int** num_pp = &num_p;

结果如下表?

VARIABLE|ADDRESS   ADDRESS|VALUE
num     |0001      0001   |4
num_p   |0002      0002   |0001
num_pp  |0003      0003   |0002

等等?如果是这样,如果初始变量不是int 而是struct,同样的逻辑是否成立?

编辑:查看有关此问题的 cmets 以了解地址的实际外观,而不是 000100020003 方案。

编辑 2:This answer to this question 指出变量不一定必须有地址这一事实。 This answer to an earlier question 也参与其中。

【问题讨论】:

  • 大致:是的。除了你的地址自然是无稽之谈,它们的偏移量会随着使用的变量的大小而变化。您应该编写一个程序,然后找到链接器映射文件输出,看看您的变量在哪里结束。
  • 嗯,不完全是。许多处理器上的内存是字节可寻址的,“地址”是一个字节地址。通常,块中的地址被描述为从 0 开始,而不是 1,因此“num”将位于地址“0000”,并且由于 int var 通常占用 4/8 个字节,“num_p”将从 0004/0008 开始。
  • @Lundin 哦,我不知道你能做到这一点。我一定会尝试的。
  • @MartinJames 好的,这是有道理的。感谢您的澄清。
  • @NetherGranite 好吧,取决于编译器和系统,地图文件可能有意义,也可能没有意义。在某些系统上,它只显示链接器将各种 .o 文件的输出转储到何处,这并不是很有趣。

标签: c pointers variables memory


【解决方案1】:

是的,您用表格说明的内容大致正确。变量名称在编译时分配给地址。这称为“符号表”,类似于您问题中的左侧表。当程序运行时,变量名不再出现在可执行文件中,只有右边表格中的地址。

如果是这样,如果初始变量不是 int 而是 struct,同样的逻辑是否成立?

是的,struct 是一个值,因此将地址分配给变量和将值分配给该地址的工作方式相同。不同之处在于struct 可能比int 占用更多内存,具体取决于其成员。这会影响下一个变量可用的地址。

请注意,分配的地址将与某些基本内存地址发生偏移。当操作系统加载可执行文件时,它会给出这个基地址,并且可执行文件通过将偏移量添加到基地址来计算绝对内存地址。

如果您有兴趣详细了解其工作原理,可以更详细地研究编译器和操作系统。

【讨论】:

  • 基内存地址是指内存段,对吧?
  • @machine_1 是的,这听起来像我的意思。自从我对这些概念做任何事情以来已经有一段时间了,所以我的术语并不准确。我也给出了一个挥手的答案,让 OP 对这里发生的事情有一个一般的、高级的想法。
  • 您首先的描述仅适用于静态变量。函数局部变量的地址在编译时是未知的。
  • @M.M 你是对的,任何变量的确切物理地址在编译时都是未知的。所有地址都由编译器计算为偏移量。静态变量的地址相对于分配给程序的基地址,局部变量的地址相对于堆栈帧的开头。当然,编译器可能会优化一些变量并将它们分配给寄存器。就这个问题而言,所有这些都过于详细了。
【解决方案2】:

如果初始变量不是 int 而是一个结构体?

结构是一种类型(如 int、double、char ...)而不是变量,所以是的,您所描述的内容也将适用。

【讨论】:

    【解决方案3】:

    还有一点值得一提的是,变量不一定要有内存地址。

    编译器可能决定对变量使用寄存器,或者地址可能在堆栈上,在这种情况下,它只是sp(堆栈指针)的偏移量。它甚至可以混合起来。一个变量的作用域和生命周期可以由编译器存储在一个寄存器中,然后在另一个寄存器中,然后在内存中移动,然后再次加载并存储在寄存器中。或者只是用一个值替换它(常量传播)或完全优化它。

    【讨论】:

      猜你喜欢
      • 2018-01-24
      • 2012-09-26
      • 2020-03-15
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-23
      相关资源
      最近更新 更多