变量范围

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

从技术上讲,C不使用堆栈。 如果您查看C99标准 ,您将找不到对堆栈的引用。 它可能与C ++标准相同,尽管我还没有检查过它。

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

你实际问的问题是,“为什么C和C ++ 编译器使用硬件堆栈来存储具有自动扩展的变量?”

正如其他人所提到的,C和C ++语言定义都没有明确说明变量必须存储在堆栈中。 它们只是定义具有不同存储持续时间的变量的行为

6.2.4对象的存储持续时间

1对象具有确定其生命周期的存储持续时间。 有三个存储持续时间:静态,自动和已分配。 分配的存储在7.20.3中描述。

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

3使用外部或内部链接声明标识符的对象,或者使用存储类说明符static声明的对象具有静态存储持续时间 。 它的生命周期是程序的整个执行,它的存储值只在程序启动之前初始化一次。

4声明标识符没有链接且没有存储类说明符static具有自动存储持续时间

5对于没有可变长度数组类型的对象,其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束。 (输入一个封闭的块或调用一个函数会暂停,但不会结束当前块的执行。)如果以递归方式输入该块,则每次都会创建一个新的对象实例。 对象的初始值是不确定的。 如果为对象指定了初始化,则每次在执行块时达到声明时都会执行初始化; 否则,每次达到声明时,该值将变为不确定。

C语言标准,草案n1256 。

毫无疑问,第5段是用硬件堆栈编写的,但有些奇怪的架构不使用硬件堆栈,至少不像x86那样。 硬件堆栈简单地使第5段中指定的行为易于实现。

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

堆栈分配要快得多,因为它真正做的就是移动堆栈指针。 使用内存池,您可以从堆分配中获得可比较的性能,但这会带来轻微的复杂性和自身的麻烦。

在堆中有另一层间接,因为在获得正确的对象之前,您必须从堆栈 – >堆转移。 此外,堆栈对于每个线程都是本地的,并且是inheritance线程安全的,其中堆是免费的所有内存

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

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

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

使用堆栈允许递归。

因为堆栈是内存的一部分,当范围结束时,堆栈将自动丢弃。 这就是有时将局部变量称为“自动”的原因。 调用中的局部变量与对同一函数的递归或multithreading调用“隔离”。

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

当有跳转时,推送局部变量并执行跳转。 返回范围时,会弹出局部变量。