存储类别说明符

作者:追风剑情 发布于:2020-1-9 21:45 分类:C

       关键字static和extern的含义取决于上下文。C语言有6个关键字作为存储类别说明符:autoregisterstaticextern_Thread_localtypedef。typedef关键字与任何内存存储无关,把它归于此类有一些语法上的原因。尤其是,在绝大多数情况下,不能在声明中使用多个存储类别说明符,所以这意味着不能使用多个存储类别说明符作为typedef的一部分。唯一例外的是_Thread_local,它可以和static或extern一起使用。

      auto说明符变量是自动存储期,只能用于块作用域的变量声明中。由于在块中声明的变量本身就具有自动存储期,所以使用auto主要是为了明确表达要使用与外部变量同名的局部变量的意图。

      register说明符也只用于块作用域的变量,它把变量归为寄存器类别,请求最快速度访问该变量。同时,还保护了该变量的地址不被获取。

      用static说明符创建的对象具有静态存储期,载入程序时创建对象,当程序结束时对象消失。如果static用于文件作用域声明,作用域受限于该文件。如果static用于块作用域声明,作用域受限于该块。因此,只要程序在运行对象就存在并保留其值,但是只有在执行块内的代码时,才能通过标识符访问。块作用域的静态变量无链接。文件作用域的静态变量具有内部链接。

      extern说明符表明声明的变量定义在别处。如果包含extern的声明具有文件作用域,则引用的变量必须具有外部链接。如果包含extern的声明具有块作用域,则引用的变量可能具有外部链接或内部链接,这链接取决于该变量的定义声明。

小结:存储类别

      自动变量具有块作用域、无链接、自动存储期。它们是局部变量,属于其定义所在块(通常指函数)私有。寄存器变量的属性和自动变量相同,但是编译器会使用更快的内存或寄存器储存它们。不能获取寄存器变量的地址。

      具有静态存储期的变量可以具有外部链接、内部链接或无链接。在同一个文件所有函数的外部声明的变量是外部变量,具有文件作用域、外部链接和静态存储期。如果在这种声明前面加上关键字static,那么其声明的变量具有文件作用域、内部链接和静态存储期。如果在函数中用static声明一个变量,则该变量具有块作用域、无链接、静态存储期。

      具有自动存储期的变量,程序在进入该变量的声明所在块时才为其分配内存,在退出该块时释放之前分配的内存。如果未初始化,自动变量中是垃圾值。程序在编译时为具有静态存储期的变量分配内存,并在程序的运行过程中一直保留这块内存。如果未初始化,这样的变量会被设置为0。

      具有块作用域的变量是局部的,属于包含该声明的块私有。具有文件作用域的变量对文件(或翻译单元)中位于其声明后面的所有函数可见。具有外部链接的文件作用域变量,可用于该程序的其他翻译单元。具有内部链接的文件作用域变量,只能用于其声明所在的文件内。

示例

partb.c文件

#include <stdio.h>

// 引用式声明,外部链接
extern int count;
// 静态定义,内部链接
static int total = 0;
// 函数原型
void accumulate(int k); //在此文件中为可选 (即可省略原型声明)

void accumulate(int k) // k具有块作用域,无链接
{
	// 静态,无链接
	static int subtotal = 0;
	if (k <= 0)
	{
		printf("loop cycle: %d\n", count);
		printf("subtotal: %d; total: %d\n", subtotal, total);
	}
	else
	{
		subtotal += k;
		total += k;
	}
}

Main.c文件

//Visual Studio中加上这句才可以使用scanf()
//否则只能使用scanf_s()
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//malloc()、free()
#include <stdlib.h>
#include <time.h>

void report_count();
void accumulate(int k);
int count = 0; // 文件作用域,外部链接

//argc: 参数个数 argv[]: 参数数组
//int main(int argc, char **argv)
int main(int argc, char *argv[])
{
	int value; // 自动变量
	register int i; // 寄存器变量

	printf("Enter a positive integer (0 to quit): ");
	while (scanf("%d", &value) == 1 && value > 0)
	{
		++count; //使用文件作用域变量
		for (i = value; i >= 0; i--)
			accumulate(i);
		printf("Enter a positive integer (0 to quit): ");
	}
	report_count();

	system("pause");
	return 0;
}

void report_count()
{
	printf("Loop executed %d times\n", count);
}

运行测试

1111.png

标签: C语言

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号