变量范围

问题描述:

为什么局部变量在C/C++中使用Stack?变量范围

+0

总是可以检出[wikipedia](http://en.wikipedia.org/wiki/Call_stack)。它有一个关于调用堆栈的体面的文章。 – phaxian 2011-03-03 16:30:48

+0

@ user643307 +1还没有想过。 – Algorithmist 2011-03-03 16:43:55

+1

他们还应该使用什么,优先级队列? – 2011-03-03 17:05:00

从技术上讲,C不使用堆栈。如果你看看C99 standard,你会发现没有参考堆栈。对于C++标准来说可能是一样的,尽管我没有检查它。

堆栈只是大多数编译器用来实现C自动存储语义的实现细节。

+1

在数学上,单向函数调用和'return'在C和C++标准中描述了引起其必然是一个堆叠/ LIFO的结构。 (通过额外的操作来支持'longjmp'和异常。) – 2011-03-03 17:03:37

局部变量对于调用堆栈中的帧是本地的。

使用堆栈允许递归。

因为堆栈是内存的一部分,当范围结束时它会自动放弃。这是有时将局部变量称为“自动”的原因。调用中的局部变量与对相同函数的递归或多线程调用“绝缘”。

+0

什么都不是自动的 - 它们被编译器生成的代码清除。 – Andrey 2011-03-03 16:29:50

+0

@Andrey,这是真实的,但术语“自动”来自K&R – 2011-03-03 16:31:11

它取决于存储变量的实现。 有些电脑甚至可能没有“堆栈”:D

除此之外,通常在调用函数来记录返回地址以及其他一些事情时,可能会进行一些维护。许多编译器实现不是为局部变量创建另一个内部维护方法,而是选择使用已经存在的方法来实现堆栈,只需要很少的更改。

本地数据存储 - 子程序经常需要存储空间来存储局部变量的值,这些变量只在活动子程序中知道,并且在返回后不保留值。通过简单地移动堆栈顶部以提供空间来分配空间用于此用途通常是方便的。与堆分配相比,这是非常快的。请注意,子程序的每次单独激活都会为本地人在堆栈中获得自己的独立空间。

堆栈分配速度要快得多,因为堆栈分配真的是移动堆栈指针。使用内存池,您可以从堆分配中获得可比较的性能,但这会带来一些额外的复杂性和自身的问题。

在堆有间接的另外一层,因为你会从 栈去 - >堆前,你得到正确的对象。此外堆栈当地的 每个线程,并inherintly线程安全的,那里的堆是免费为所有 内存

您实际询问的问题是“为什么C和C++ 编译器使用硬件堆栈来存储具有自动范围的变量?”如其他人所提到的,C语言和C++语言定义都没有明确说变量必须存储在堆栈中。它们简单地定义的变量行为具有不同存储持续时间:

6.2.4对象

1的存储持续时间的对象具有一个 存储持续时间决定其寿命。有三种存储时间:静态,自动和分配。分配的存储在7.20.3中描述。

2对象的 生命周期是程序执行的一部分,在此期间保证为其保留存储 。一个对象存在,具有一个常数地址 ,25),并在其整个生命周期中保留其最后存储的值 。 26)如果一个对象在其生命周期之外引用,则行为是未定义的。指针的值在其指向的对象达到其生命周期结束时变得不确定。

3对象的标识符声明为外部或内部链接,或与 存储级别说明符 static具有 静态存储持续时间。它的使用期限是整个程序的执行 ,并且在程序 启动之前,其存储值仅被初始化一次。

4一个对象的标识符声明为没有链接并且没有存储级别 说明符 static具有 自动存储持续时间

5对于不具有可变长度数组类型的对象,其使用期限从输入到与其关联的块中延伸 ,直到该块的执行以任何方式以 结束为止。 (输入一个封闭的块或调用一个函数会挂起,但不会结束,执行当前块。)如果块是递归输入的,则每次创建一个新对象 对象。对象的初始值是不确定的。如果为对象指定了初始化,则在执行块时每次执行声明时都会执行 ;否则,该值在达到声明时变得不确定。

C语言标准,草案n1256

号第5款的设计考虑了硬件堆栈书面质疑,但也有古怪的架构,在那里,不以同样的方式使用硬件堆栈,至少不会像类似的x86。硬件堆栈简单地使第5段中指定的行为易于实现。

局部变量局限于它们可以访问的范围。 使用堆栈可以将控制从一个范围跳转到另一个范围,并在返回时继续初始存在的局部变量。

当有跳转时,推动局部变量并执行跳转。在返回到作用域时,局部变量被弹出。