C语言存储类别

发布时间 2023-09-16 19:02:21作者: ^_^ok

对于C语言中的变量,存储类别可分为4种:auto(自动存储)、static(静态存储)、register(寄存器存储)、extern(外部存储)。

  • auto自动存储

    函数中的局部变量,如果不专门声明为(static)静态存储类别,都是动态地分配存储空间的,数据存储在动态存储区中

    形参与函数中定义的局部变量,都是自动变量(动态局部变量),在调用结束就会自动释放这些存储空间。也就是说,它们存储于栈区

  • static静态存储

    静态变量属于静态存储,用static关键字声明。静态变量是在编译期间被初始化的,且只能初始化一次,在整个程序运行期间静态变量不被释放。若程序没有对静态变量初始化,则编译时自动赋初值0(对数值型变量)或空字符'\0'(对字符变量),这与动态变量不同,因为动态变量未初始化时是不确定的值。虽然静态变量在整个程序运行期间不被释放,但他也只能在其作用域可见,也就是说,对于某个函数的静态局部变量,其他函数是不可以调用它的。

  • register寄存器变量

    顾名思义,寄存器变量就是存储在寄存器中的变量。一般是用于一些需要频繁读取的变量,为了提高存取效率,把局部变量放在CPU中的寄存器中,直接从寄存器中存取。

  • extern外部变量

    外部变量也称为全局变量,是定义于所有函数之外的变量,其作用域是其定义(或声明)之后的所有函数。函数可以访问外部变量的前提是在该外部变量的定义(或声明)在该函数定义或声明之前。外部变量只能初始化一次!外部变量通过关键字extern声明。

注意,当局部变量和全局变量重名时,用的是局部变量。

下面是extern的一个简单用法示例

#include <stdio.h>
//声明时也可以放这里 extern int a;
void print() {
	extern int a;  //由于外部变量a的定义在该函数之后,所以需要声明。且声明的时候一定要加关键字extern
	               //若a定义在print函数前面,则可以不用声明
	printf("%d", a);
}

int a = 5;

int main() {
	print();
	return 0;
}

对于C语言的内存分配与变量的存储位置,可以参考示意图
image

堆和栈可参考堆和栈

  • auto变量存放在栈区
  • 程序员调用malloc申请的空间在堆区
  • 数据区
    • 静态变量(全局和局部)存放在全局(静态)区,包括已初始化和未初始化的变量
    • 常量字符串、数字等存放在常量区,加了const关键字常量也存放在常量区
  • 代码区存放程序执行代码,其值不能修改

文章C语言:内存分配---栈区、堆区、全局区、常量区和代码区_堆内存和栈内存图解有对全局区更详细介绍

全局(静态)区介绍
通常是用于那些在编译期间就能确定存储大小的变量的存储区,但它用于的是在整个程序运行期间都可见的全局变量和静态变量。
全局区由 .bss段 和 .data段组成,可读可写。
.bss段
未初始化的全局变量和未初始化的静态变量存放在.bss段。
初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
.bss段不占用可执行文件空间,其内容由操作系统初始化。
.data段
已初始化的全局变量存放在.data段。
已初始化的静态变量存放在.data段。
.data段占用可执行文件空间,其内容有程序初始化。

image

参考文章

  1. C语言_存储类别
  2. C语言四大存储区域总结
  3. C语言:内存分配---栈区、堆区、全局区、常量区和代码区_堆内存和栈内存图解