昨天我接受采访时,面试官向我询问了存储变量的存储类。
我的回答是战争:
Local Variables are stored in Stack.
Register variables are stored in Register
Global & static variables are stored in data segment.
The memory created dynamically are stored in Heap.
他问我的下一个问题是:为什么他们会被存储在那些特定的内存区域?为什么Local variable
不存储在{{ 1}}(虽然我需要在我的程序中经常使用register
变量)?或者为什么全局变量或静态变量auto
存储在not
?
然后我一无所知。请帮帮我。
答案 0 :(得分:16)
因为存储区域确定变量的 范围 和 生存期 。
根据您的要求选择存储规格,即:
终身时间: 您希望特定变量需要存活且有效的持续时间。
范围: 您希望变量可以访问的范围(区域)。
简而言之,每个存储区域提供不同的功能,您需要各种功能,因此存储区域不同。
答案 1 :(得分:12)
实际上,C语言没有定义任何变量的存储位置。但是,它确实定义了三个存储类:静态,自动和动态。
静态变量在程序初始化期间(main()
之前)创建,并一直存在,直到程序终止。文件范围('全局')和静态变量属于该类别。虽然这些通常存储在数据段中,但C标准并不要求这样,在某些情况下(例如,C解释器),它们可能存储在其他位置,例如堆。
自动变量是在函数体中声明的局部变量。它们是在程序流程到达声明时或之前创建的,并在它们超出范围时被销毁;为递归函数调用创建了这些变量的新实例。堆栈是实现这些变量的方便方式,但同样,它不是必需的。如果你选择的话,你也可以在堆中实现自动化,并且它们通常也放在寄存器中。在许多情况下,自动变量将在其生命周期内在堆栈和堆之间移动。
请注意,自动变量的register
注释是提示 - 编译器没有义务对它做任何事情,事实上许多现代编译器完全忽略它。
最后,动态对象(C中没有动态变量)引用使用malloc
,calloc
或其他类似分配函数显式创建的值。它们在显式创建时存在,并在显式释放时被销毁。堆是放置这些的一个方便的地方 - 或者更确切地说,一个堆基于执行这种分配方式的能力来定义堆。但同样,编译器实现可以随意做任何事情。如果编译器可以执行静态分析来确定动态对象的生命周期,它可能能够将其移动到数据段或堆栈(但是,很少有C编译器执行此类“转义分析”)。
这里的关键点是C语言标准只定义给定值存在多长时间。并且这个生命周期的最小界限 - 它可能会比所需的更长。究竟如何将它放在内存中是一个主题,语言和库的实现给予了很大的自由。
答案 2 :(得分:1)
实际上它只是一个方便的实现细节。
如果他愿意,编译器可以在堆上生成局部变量。
在堆栈上创建它们更容易,因为在离开函数时,您可以根据堆栈的增长方向通过简单的加/减来调整帧指针,从而自动释放下一个函数的已用空间。然而,在堆上创建本地人意味着更多的管家工作。
另一点是不能在堆栈上创建局部变量,如果编译器认为更合适并且有足够的寄存器来执行,则可以在寄存器中存储和使用局部变量。
答案 3 :(得分:0)
在大多数情况下,局部变量存储在寄存器中,因为当你进行函数调用时,寄存器被从堆栈中推出并加载它看起来像是在堆栈上。
实际上没有像寄存器变量那样的东西,因为它只是C中一些很少使用的关键字,它告诉编译器尝试将它放在寄存器中。我认为大多数编译器都会忽略这个关键字。
这就是为什么问你更多,因为他不确定你是否深刻理解话题。事实上,寄存器变量实际上是堆栈。
答案 4 :(得分:0)
在嵌入式系统中,我们有不同类型的存储器(只读非易失性(ROM),读写非易失性(EEPROM,PROM,SRAM,NVRAM,闪存),易失性(RAM)),我们也有不同的要求(在电力循环后,不能改变也可以持续,在电力循环后可以改变,并且在任何时候都可以改变)我们拥有的数据。我们有不同的部分,因为我们必须乐观地将我们对数据的要求映射到不同类型的可用存储器。