2012-02-12 49 views
2

请考虑以下C函数。
是否打开大括号以创建局部范围使编译器在堆栈上创建记录以维护范围中声明的变量?堆栈上的本地范围记录

void function() 
{ 
    int q,r; 
    ... 
    { 
     int i = 0; 
     int j = 3; 
     q = j + 1; 
    } 
    ... 
} 

如果是这样,编译器采取同样用,而块?

例如:

void function() 
{ 
    int q,r; 
    ...  
    while(conditions) 
    { 
     int i = 0; 
     int j = 3;  
     q = j + 1;  
    } 
    ... 
} 

回答

4

不是由C标准中指定的堆叠的布置。

花括号({})引入了一个新的范围,所以原则上,这可以在堆栈上创建一个新框架。但编译器可能会选择优化这个开销。

1

这取决于编译器。良好的现代编译器会优化这些代码。这将在编译时计算

int j = 3; 
q=j+1; 

和制造类似

q=4; 

同为第二个例子。变量j将被放置在堆栈中,甚至可能放入一个寄存器中,其值设置为3,然后通过循环迭代进行处理。

1

{}被称为复合语句(也称为块),它引入了一个新的块范围。这意味着在这里:

void function(void) 
{ 
    int q,r; 
    ... 

    { 
     int i = 0; 
     int j = 3; 
     q = j + 1; 
    } 
    ... 

}

qr在函数结束时被销毁; ij在本地块范围的末尾被销毁。自动对象的生命周期仅限于声明的块。

对于喜欢while语句循环语句,这是完全一样的,while陈述的定义为:

while (expression) statement 

如果您在while使用的语句复合语句(块)也将引入新的范围。

现在在堆栈级别上,C不需要堆栈,因此它的实现细节。

+0

所以q,r和i,j可以在不同的记录上创建? – GionJh 2012-02-12 12:50:36

+0

@ user986437'q','r'和'i','j'具有不同的词汇范围和不同的生存期。 – ouah 2012-02-12 12:53:23

+0

请注意,while循环中的'i'和'j'在循环的每次迭代中都重新初始化。 – 2012-02-12 13:15:41

0

根据我以前见过的行为,我会说“可能不是”。 IME,只为所有函数的变量创建一个单独的堆栈框架,而不管它们在函数中的作用域如何。

受限范围是编译器在翻译时强制执行的事情;在运行时并没有真正的需要。

+0

我看到...请帮我清楚这一点。让我们假设我有一台带有几kb RAM的电脑,会为程序员创建的每个范围使用一个记录,以帮助大型程序在我的电脑上运行? – GionJh 2012-02-12 15:38:57

+0

语法更正* kbytes – GionJh 2012-02-12 16:52:52

+0

如果您真的对内存有限制,则为每个范围创建整个堆栈帧可能会使情况变得更糟*。更不用说它会造成运行时性能损失。 – 2012-02-12 22:59:49