在本教程中,您将学习关于 C 语言中存储类的所有知识,以及存储类的不同分类,如 auto、register、static 和 extern,并通过一些简单的示例进行解释。
C 语言中的存储类描述了变量或函数存储地址的属性。这意味着存储类用于确定变量的位置、作用域或生命周期以及初始值。RAM 内存、CPU 寄存器是通常保存这些值以供程序未来作用域和可见性使用的地方。在 C 语言编程中,存储类可以通过将其分类为“全局”或“局部”来确定变量的生命周期。它们基本上有四种存储类
每个类也都有相关的存储类说明符。任何存储类的作用都是告诉或命令编译器——“如何存储特定的变量或函数”。说明符的声明语法如下
storage_class_specifier variable_type variable name;
您只能在单个声明语句中声明一个存储类说明符。
在没有存储类说明符的情况下,内存分配遵循以下规则
具有外部链接的“static”文件作用域变量只能在后续文件中使用。而具有“外部链接”的变量在程序中的所有文件中都可以自由使用。局部变量是独一无二的,因为它们没有任何类型的链接。因此,它们只能在声明它们的代码块内部使用。
使用“auto”说明符声明的变量属于自动存储类。默认情况下,所有没有任何说明符的类型或变量都被认为是这种类型。自动变量的作用域和可见性仅限于定义它的函数。因此,当退出函数块时,为自动变量分配的内存会被释放。由此我们可以推断,自动变量的内存分配是动态完成的。在考虑初始化部分时,默认情况下,C 语言中的自动变量被初始化并赋为一个垃圾值。
考虑以下程序
#include <stdio.h>
main() {
auto int a = 1; {
auto int a = 2; {
auto int a = 3;
printf("\n%d ", a);
}
printf("%d ", a);
}
printf("%d", a);
}
输出为 '3 2 1'。
在这个程序中,一个整型变量用相同的名称“a”定义了三次,但编译器没有显示任何错误。这是因为“a=3”的存在仅限于第三个块内。一旦执行完成,第二层块(其中 a=2)获得控制权,变量名称“a”或“a=3”就不复存在了。现在“a”是一个全新的标识符,您可以自由指定任何您想要的值。因此,循环继续,并使用同一个变量“a”打印出“3 2 1”。
寄存器存储类属于自动存储类的范畴,因为这里声明的存储类也只在其被声明的块内起作用。区别在于访问速度。我们知道计算机内存或 RAM 的工作速度比寄存器慢一些,寄存器的存储容量较小。因此,将存储类声明为“register”会告诉编译器将其存储在 CPU 寄存器中,并且将来会频繁访问它们。但缺点是,只有少数选定的变量可以存储在这种存储类中,并且您无法访问确切的地址位置(使用“&”)。另一个限制是不能分配初始值,但使用这种存储类可以显著减少编译时间。
C 语言中的静态存储类用于声明静态变量,这些变量会被分配一个初始值零。静态变量的关键字说明符是 static。虽然这些变量不能在其定义的函数外部使用,但最重要的特性是,即使块的执行完成,它也不会丢失其值,而是会一直保持到主函数运行结束。
#include <stdio.h>
int show() {
int a = 10;
static int s = 10;
printf("a=%d\t s=%d\n", a, s);
a = a + 1;
s = s + 1;
}
main() {
show();
show();
show();
}
输出
a=10 s=10 a=10 s=11 a=10 s=12
因此,每次执行“show()”时,静态变量的值都会打印出每个循环最后赋的值,而不是初始值。而自动存储类每次都将“a”定义为 10,并相应地打印出来。
属于外部存储类的任何变量都可以在一个块中定义,并同时在另一个块或段中使用。extern 说明符向编译器指示存在外部链接。因此,它的作用就像一个具有初始赋值的全局变量。它能够在一个大型程序中的两个不同文件中工作。它由关键字“extern”定义,例如
extern int x;
extern show();