如果试图用extern static修饰一个变量声明,编译器会给出一个错误信息"more than one storage class may not be specified"。那么为什么会报错呢?
extern和static是用来声明变量存储类型的。我们知道静态变量用static修饰,其目的是声明一个变量只能被此文件里的函数享有。因而它的主要工作就是防止变量被外部函数使用。而extern存储类型的目的却是允许几个源文件可以共享同一个变量。两者的功能南辕北辙,编译器当然不会答应他俩修饰同一个变量。
使用static存储类型声明变量的好处包括两点:
1. 易于维护。 由于static变量或者函数在其他文件不可见,因此对其进行修改不会影响其他文件的变量或者函数。
2. 减少"名字空间污染"。 由于static变量具有内部链接特性,所以可以在其他文件中重复使用这些名字。
一般来说,声明具有以下形式:
[声明] 变量说明符 声明符;
声明说明符描述声明的变量或者函数的性质,声明符给出了他们的名字。声明说明符分为以下3大类:类型限定符、存储类型和类型说明符。
1. 类型限定符
类型限定符 | 说明及用法 |
---|---|
const | const类型的对象在程序执行期间不能够被修改 |
volatile | 修饰词volatile告诉编译器不需要优化volatile声明的变量,让程序可以直接从内存读取变量。因为编译器会对于一般的变量进行优化,将内存中的变量值保存在寄存器中,从而加快读写速度 |
restrict | C99增加的新类型限定符,表明restrict修饰的指针是唯一能访问它所指向对象的方式 |
2. 存储类型
在总结存储类型之前,我们先看一下变量性质的划分。
2.1. 变量性质
变量性质 | C程序中每个变量具有以下3个性质 |
---|---|
存储期限 | 决定了为变量预留和内存被释放的时间,包括自动存储期限和静态存储期限 |
作用域 | 指可以引用变量的那部分程序文本,包括块作用域和文件作用域 |
链接 | 确定了程序的不同部分可以共享此变量的范围,包括外部链接,内部链接和无链接 |
2.2. 存储类型
变量默认的存储类型、作用域和链接依赖于变量声明的位置。
存储类型 | 在块内部声明 | 在程序外部声明 |
---|---|---|
auto | 自动存储期限、块作用域、无链接 | 自动存储期限、文件作用域、外部链接 |
static | 静态存储期限、块作用域、无链接 | 静态存储期限、文件作用域、内部链接 |
extern | 自动存储期限、块作用域、链接? | 静态存储期限、文件作用域、链接? |
register | 自动存储期限、块作用域、无链接 | 只对块内部变量有效 |
3. 类型说明符
类型说明符 | 说明及用法 |
---|---|
常见 | char, int, short, long, float, double, signed, unsigned |
结构体 | struct |
联合体 | union |
枚举 | enum |
typedef自定义 | typedef创建的类型名 |