简体   繁体   English

C:内存中的循环,条件,结构

[英]C: Loops, conditions, structs in memory

This question may sound trivial but, I know that whenever a function starts executing a stack frame is created in the stack for all local variables of the function etc. but I cannot understand is what happens when a for loop starts executing or the code inside an if condition starts being executed. 这个问题听起来很琐碎,但是,我知道每当一个函数开始执行时,都会在堆栈中为该函数的所有局部变量创建一个堆栈框架,但是我无法理解,当for循环开始执行时,或者内部的代码发生了什么如果条件开始执行。 Seems unreasonable to think of them as being executed inside the stack frame of the function, since they have their own scope and thus their own local variables. 将它们视为在函数的堆栈框架内执行似乎是不合理的,因为它们具有自己的作用域,因此也具有自己的局部变量。 But, they can access variables of the functions above them, thus this seems to imply that they are inside the stack frame of a function. 但是,它们可以访问它们上面的函数的变量,因此这似乎暗示它们在函数的堆栈框架内。

So can anybody clear this up for me? 那么有人可以帮我解决这个问题吗?

Where are they actually located in memory when being executed? 它们在执行时实际位于内存中的什么位置?

The same question arises for structs, they have their own scope, and they are not pointers but just bigger 'boxes' containing integers, char*s etc. 对于结构,也会出现同样的问题,它们具有自己的作用域,它们不是指针,而只是包含整数,char * s等的更大的“盒子”。

A loop (or any other block-like construct, such as an if-else statement) is not similar to a function. 循环(或任何其他类似块的构造,例如if-else语句)与函数相似。 A function is an autonomous entity. 功能是一个自治实体。 It's in itself a complete piece of computation. 它本身就是完整的计算过程。 When you call a function, the instructions, statements and expressions of a function can only access – apart from globals – the function's local variables and parameters (the trick is that parameters can be bound to a calling function's locals, their address, etc.). 调用函数时,除全局变量外,函数的指令,语句和表达式只能访问函数的局部变量和参数(窍门是可以将参数绑定到调用函数的局部变量,其地址等)。 。

However, a loop, an if-else or any other kind of block is part of a function. 但是,循环,if-else或任何其他类型的块是函数的一部分 It is not a separate unit of computation. 不是单独的计算单位。 They are not "called". 他们不是“被称为”。 They are simply reached and executed. 只需达到并执行它们即可。

The fact that blocks have scope doesn't mean that they need a separate stack frame. 块具有作用域的事实并不意味着它们需要单独的堆栈框架。 A stack frame is not created when a new scope is entered. 输入新的作用域时,不会创建堆栈框架。 A stack frame is created when a function is called, because the stack is related to control flow management (eg frames need to save the return address of the function too.) 调用函数时会创建一个堆栈框架,因为该堆栈与控制流管理有关(例如,框架也需要保存该函数的返回地址。)

Yeah, allocation and destruction of variables in nested scopes can be represented by a stack, but that is not the call stack. 是的,嵌套作用域中变量的分配和销毁可以由堆栈表示,但不是调用堆栈。 That's rather some sort of a "scope stack", and it's purely conceptual. 那是某种“范围堆栈”,纯粹是概念上的。 Let me demonstrate this with an example: 让我用一个例子来说明这一点:

void foo()
{
    int a = 42;       // 'a' is declared and is in scope.
                      // Let's pretend its address is 0x1000.

    {
        int b = 1337; // 'b' is declared and in scope.
                      // Let's pretend its address is 0x1004.
    }

    // here, 'b' is destroyed. Nothing is "popped" out of the stack
    // at runtime – it's merely that the compiler can detect that the
    // name 'b' is not in scope anymore. And hence:

    int c = 0; // it may now reuse the former address of 'b', 0x1004,
               // for storing 'c'.
               // Each of these 3 variables reside within the same stack frame.
}

As for structs: that's something completely different, again. 至于结构:再次完全不同。 If you declare a variable of struct type, then a large enough chunk of memory will be allocated to hold all members of the struct in order. 如果声明结构类型的变量,则将分配足够大的内存以按顺序容纳结构的所有成员。 Memory-wise, "there is no struct". 在内存方面,“没有结构”。 There are only members of the struct, allocated one-by-one, aligned properly. 只有结构的成员 ,它们被一一分配,并正确对齐。 A struct is just an abstraction. struct只是一个抽象。

In practical reality, the variable exists in the main stack frame of the function. 实际上,该变量存在于函数的主堆栈框架中。 You just can't refer to it anywhere outside the sub-block in which it's declared. 您只是不能在声明它的子块之外的任何地方引用它。 It's not really as if the variable is constantly created and destroyed each time through the loop. 并不是每次循环都会不断创建和销毁变量。 So it's more an issue of where the compiler allows you to refer to it by its name, not of its actual existence. 因此,更多的问题是编译器允许您通过其名称而不是其实际存在来引用它。

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

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