当存储非指针值时,C中实际发生了什么? [重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当存储非指针值时,C中实际发生了什么? [重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

重要提示:这曾试图同时询问太多事情,并且误导,因为我是在一个关于如何使用指针的错误假设下写的,并且它最终看起来像是重复的。请改为:How are variables tied to their values in C?


让我们考虑在地址4处有一个值0001,然后我们将地址0001分配给变量num。我们可以把它想象成两个表:

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

据我所知,这将是以下代码的最终产品:

int temp = 4;
int * num = &temp;

然而,在第一行,int temp = 4;发生了什么?第一行是否会产生这样的东西?

VARIABLE|ADDRESS    ADDRESS|VALUE
        |           temp   |4

指针的指针是如何工作的?代码是:

int temp = 4;
int * num = &temp;
int ** pnum = #

产生这个?

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

想到这个的正确方法是什么?引擎盖下究竟发生了什么?此外,当存储结构而不是数字时,这会如何变化?

据我所知,上述例子可能完全不正确;他们只是将我的问题置于语境中。

答案

并非所有变量都需要在存储器系统中具有地址,一些变量足够短,以至于它们可以在寄存器中存活整个寿命。在这种情况下,编译器会将它们分配(重命名)为eaxebxr1r2。寄存器是CPU中可以保存可变内容的插槽。

因为许多架构具有有限的寄存器编号(8个虚拟(机器语言可见)x86-64中的寄存器,IA64中的256个寄存器...)其余的变量被分配(编译)到内​​存中的地址,这将总是在堆栈上。堆栈(由esp寄存器跟踪,一个特殊的寄存器)是一个支持操作系统的后进先出分配器(内存页面随着它的增长而生效)所以编译器只需要获取当前的堆栈指针并将其递增要分配的变量的大小,这是变量的地址。

与您演示的第一种情况一样,值分配是通过发出带有硬编码值的mov汇编命令来完成的,因此该常量存在于程序的内存空间中。这意味着价值来自指令本身。 (L1:inst cache-> fetcher-> CPU pipeline-> mov-> STORE pipeline-> L1:data cache)

其余的工作就像你感觉到的那样。

以上是关于当存储非指针值时,C中实际发生了什么? [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C#中的委托是啥?事件是否一种委托?

当 GIT 用完您的修订版的哈希值时会发生啥?

C中的棘手指针算法:** k

C ++指针对象与非指针对象[重复]

当需要一个形式参数直接改变对应实参的值时,该形式参数应说明为啥参数?

我为存储在指针地址中的值分配了一个变量,那么为啥当初始值改变时它不改变呢?