我是C中一个相当初学的程序员,我一直认为变量声明的工作方式是当你声明一个像int x;
这样的变量时,你告诉编译器为该变量留出内存,然后如果你初始化它然后写了像x = 3;
这样的东西,也许编译器可能会将这个声明改组到更有效的地方,如果它可以在编译时。
但是我最近读到这不是发生的事情。那会发生什么,为什么?幕后是否有具体的事情发生,或者是否有效地声明了编译器中的消息,而它在吐出的最终二进制文件中没有模拟信息?这一切如何适用于函数声明?
这两种说法都是正确的,在C标准中处于不同的“级别”。
C标准主要描述了C实现如何在假想的抽象计算机中起作用。在此模型中,当定义变量(不仅仅是声明)时,会为其保留内存。
但是,C标准表示实际实现只需要产生结果,就像它遵循抽象模型一样。该标准规定只有抽象模型的某些部分必须是可以理解的。最值得注意的是,该程序的输出是可观察的。
由于此规则,编译器可以以任何方式更改程序的内部部分,只要输出和其他可观察行为保持不变即可。因此,当编译器看到你以某种特定方式使用某个变量x
并且它可以以另一种方式获得相同的结果而不使用x
的内存时,允许编译器更改程序,以便没有用于x
的实际内存。
我认为你的第一段很好,并且像往常一样真实。
我喜欢这样绘制图片,带有标记的小框,显示为各种变量留出的内存:
char c = 'A';
int i = 123;
int *ip = &i;
+---+
c: | A |
+---+
+---------+
i: | 123 |
+---------+
^
|
+----|----+
ip: | * |
+---------+
然后我想到的是确保每个框的内容是合适的:正确的类型,不会溢出。对于每个指针,我想一下这个小箭头是否指向有效的地方。
如果变量是本地变量,则它们通常存储在堆栈帧中。如果变量是全局变量,则它们通常存储在数据段中。但是,你是对的,他们可能会被重新安排,所以你不能指望一个人来到另一个人之前或之后。 (当然,你不想在一个理智或便携的程序中。)