C语言类型限定符

通过类型限定符可以修改声明中的类型,类型限定符有 const、volatile、restrict 和 _Atomic。声明中可使用多个类型限定符,它们的顺序没有限制。

类型限定符列表内可以多次出现相同的类型限定符,或者通过限定 typedef 名称的方式,反复使用同一个限定符。编译器会忽略重复出现的限定符,将它们视为只出现一次。

各种类型限定符的含义如下:

(1) const
对象的类型如果采用了限定符  const,则该对象就是常量。在定义该对象之后,程序无法修改它。

(2) volatile
对象的类型如果采用了限定符 volatile,则该对象可以被其他进程或事件修改。关键字 volatile 告诉编译器在每次使用该对象值时,都要重新读取它,即便程序本身自上一次获取后再没有修改过它的值。这种限定符通常用于硬件接口编程,以防止变量值被外部事件修改后,未能及时更新。

(3) restrict
限定符 restrict 只适用于对象指针类型。这种类型限定符是 C99 新增加的,用来告诉编译器,一个被指针所引用的对象,如果它可以被修改,那么只能被 restrict 限定的指针修改,不能被除该指针以外的其他任何方式修改,无论是直接方式还是间接方式。该特性允许编译器采用特定优化技术,而该技术可能需要 restrict 特性的支撑。编译器也有可能会忽略限定符 restrict,而不对程序结果造成任何影响。

(4) _Atomic
采用类型限定符 _Atomic 声明的对象是一个原子对象(atomic object)。数组不能是原子对象。对原子对象的支持是可选的:C11 实现版本中,如果定义了宏 _STDC_NO_ATOMICS_,则表示程序不能声明原子对象。

编译器也可以将 const 对象存储在内存中的只读区域,但是 volatile 对象不能。如果程序不使用 volatile 对象的地址,也有可能编译器干脆不为该对象分配内存。

对象如果同时使用了限定符 const 和 volatile,如下例中 ticks 对象所示,它不能被程序本身修改,但可以被其他事件修改,例如时钟芯片的中断处理程序:
extern const volatile int ticks;

下面是使用类型限定符声明的更多示例:
const int limit = 10000;                      // 一个int常量对象
typedef struct { double x, y, r; } Circle;      // 一个结构类型
const Circle unit_circle = { 0, 0, 1 };         // 一个Circle常量对象
const float v[] = { 1.0F, 0.5F, 0.25F };        // 一个具有float常量元素的数组
volatile short * restrict vsPtr;                // 一个限定指针,指向volatile short

对指针类型来说,在星号右边的类型限定符,其限定的是指针本身,而在星号左边的类型限定符,其限定的是指针所指向的对象类型。在最后一个示例中,指针 vsPtr 使用限定符 restrict,该指针所指向的对象使用限定符 volatile。