一位经验丰富的 C 开发人员告诉我,静态变量的概念与静态内存分配的概念不同。这个对吗?如果是这样,这两个概念有什么区别?
静态内存分配的正式定义是什么?它与静态变量的正式定义有何不同?
这个问题仅涉及这些概念如何映射到 C 编程语言。
一位经验丰富的 C 开发人员告诉我,静态变量的概念与静态内存分配的概念不同。这个对吗?如果是这样,这两个概念有什么区别?
静态内存分配的正式定义是什么?它与静态变量的正式定义有何不同?
这个问题仅涉及这些概念如何映射到 C 编程语言。
本质上,静态变量是使用静态内存分配分配内存的变量。
下列术语的使用支持这一点:
GNU 的libc 手册。
- 静态分配是在声明静态或全局变量时发生的。每个静态或全局变量定义一个固定大小的空间块。当您的程序启动(执行操作的一部分)时,空间被分配一次,并且永远不会被释放。
- 当您声明一个自动变量(例如函数参数或局部变量)时,就会发生自动分配。自动变量的空间在输入包含声明的复合语句时分配,并在退出该复合语句时释放。在 GNU C 中,自动存储的大小可以是一个变化的表达式。在其他 C 实现中,它必须是常量。
K&R 第二版,附录 A,第 4.1 节“存储类”
有两种存储类:自动和静态。几个关键字与对象声明的上下文一起指定其存储类。自动对象是块的本地对象(Par.9.3),并在退出块时被丢弃。如果没有提及存储类规范,或者使用了 auto 说明符,则块内的声明会创建自动对象。声明为寄存器的对象是自动的,并且(如果可能)存储在机器的快速寄存器中。
静态对象可能是块的本地对象或所有块的外部,但在任何一种情况下,在退出和重新进入函数和块时都会保留它们的值。在一个块中,包括一个为函数提供代码的块,静态对象是用关键字 static 声明的。在所有块之外声明的对象,与函数定义处于同一级别,始终是静态的。通过使用 static 关键字,它们可以成为特定翻译单元的本地;这给了他们内部联系。通过省略显式存储类或使用关键字 extern,它们成为整个程序的全局;这给了他们外部联系。
这似乎证实了等价性。
编译器、原理、技术和工具第 7.1.1 节静态与动态存储分配
静态和动态这两个形容词分别区分编译时间和运行时间。
操作系统,基于概念的方法DM Dhamdhere,第 194 页
定义5.1(静态和动态绑定)静态绑定是在程序(或软件系统)开始运行之前执行的绑定,而动态绑定是在其运行期间执行的绑定。
[...]
静态和动态内存分配静态内存分配可以由编译器、链接器或加载器在读取程序执行时执行。动态内存分配以惰性方式执行。也就是说,内存分配是在程序执行期间第一次使用实体之前分配给实体的。
[...]
静态内存分配在程序执行期间不需要任何内存分配操作。相比之下,动态分配会产生在程序执行期间执行的内存分配操作的开销。其中一些动作甚至在程序执行期间重复多次。
Programming in C - Ajay Mittal 的实用方法。第 7.7 节,概念性问答,第 25 期,第 444 页
运行时(即程序执行时)的内存分配称为动态内存分配。
malloc
在 C 中,内存可以通过调用calloc
或realloc
函数来动态分配。编译时的内存分配称为静态内存分配
后面是一个表格,详细解释了差异。你可以在谷歌图书中看到它
内存作为 C 和 C++ 中的编程概念第 15 页:
[...] 因此我们说的是静态内存分配或(编译时的内存分配或编译器的内存分配),尽管严格来说,编译器在程序运行时不会分配任何内存。甚至在运行程序时,用于编译该程序的编译器可能不再存在。