'C' 语句如何在内存中执行

How do 'C' statements execute inside memory

假设我这里有这段 C 代码:

int main() {           
    int a = 10;
    printf("test1");
    printf("test2");
    someFunc();
    a = 20;
    printf("%d",a);
} 

好吧,我认为所有这些语句都是一次存储在堆栈中,然后一个一个地弹出以执行。我对么?如果不对,请指正。

不是真的没有。 C 标准没有提到 stack 所以你的想法是错误的。

只要遵循 C 标准,C 编译器(或解释器)就可以做任何它喜欢的事情。

在您的情况下,这可能意味着,(i) 完全删除 a,因为它仅用于在函数末尾输出 20,以及 (ii) someFunc() 如果这样做没有副作用,可以删除。

通常发生的是您的代码被转换为适合目标体系结构的机器代码。尽管现代编译器会积极优化,但这些机器代码指令确实倾向于非常忠实地遵循代码(从这个意义上讲,C 相当"low level")。

值得注意的是,C 标准并不强制执行。因此,只要根据标准输出是正确的,编译器就可以自由选择实现它。

您最有可能发生的情况是,编译器将这段 C 代码翻译成汇编代码,然后从上到下执行。

a = 20;

除非您在其他地方使用它,否则很可能已被优化掉。好的编译器也会为你抛出警告:

Warning: Unused Variable a

C 标准没有指定内存中的位置。

然而,计算机通常是这样工作的:

  • 你的程序由各种内存组成sections/segments,通常它们被称为.data.bss.rodata.stack.text并且可能还有 .heap.text 部分用于存储实际的程序代码,其余部分用于存储变量。 More info on Wikipedia.
  • C 代码由编译器翻译成机器代码(汇编程序)。所有代码都存储在 .text 部分,这是只读存储器。
  • 现代计算机可以 "mark" 内存作为代码或数据,如果您尝试在数据部分执行代码或将代码部分视为数据,将能够生成硬件异常。通过这种方式,处理器可以协助捕获悬空指针或 运行-away 代码等错误。
  • 理论上您可以从任何内存部分执行代码,甚至可以在堆栈上执行代码,但由于前面提到的功能,通常不会这样做。大多数情况下,无论如何这样做都没有任何意义。

因此对于您的特定代码片段,唯一存储在堆栈中的是变量 a。或者更可能的是,出于性能原因,它存储在 CPU 寄存器中。

字符串文字 "test1""test2""%d" 将存储在 .rodata 部分。

文字 20 可以存储在 .rodata 部分,或者更有可能合并到代码中,因此与其余代码一起存储在 .text 中。

程序计数器确定当前执行的代码部分。堆栈不涉及任何东西,它只是用于存储数据。