C语言存储类修饰符和类型限定符

存储类修饰符编程

声明中出现的存储类修饰符(storage class specifier)用于修改标识符的连接和对应对象的存储周期(连接与存储周期的概念将会在本章后面介绍)。连接(linkage)和存储周期(storage duration)是C语言中常会遇到的困扰。连接(标识符的属性)和存储周期(对象的属性)二者在声明中都会受相同关键字集(存储类修饰符)的影响。本章后面会介绍对象的存储周期能够是动态的、静态的,或已分配的(allocated),而标识符的连接能够是外部(external)、内部(internal)或不做限定的。相似“静态连接”或“外部存储”等说法在C语言中是没有意义的。注意:对象有存储周期,而非连接;标识符有连接,而非存储周期。
一个声明中不能出现多个存储类修饰符。函数标识符只可使用存储类修饰符extern或static。函数参数只可使用存储类修饰符register。5种存储类修饰符的含义以下:
auto
声明中有修饰符auto的对象,具备动态存储周期。这种修饰符只能用于函数内的对象声明。在ANSI C中,默认状况下函数内的对象声明都有动态的存储周期,因此不须要使用修饰符auto。
register
当声明对象有动态存储周期时,可使用修饰符register。该关键字告诉编译器,所声明对象的访问应该尽可能快——理想状况下,应该将该对象存储在CPU寄存器(register)中。然而,编译器可能并不会按照理想状况那样作,而是会把用register声明的对象当成普通的动态存储周期对象。无论怎样,只要采用修饰符re-gister声明了对象,就不能用地址运算符对该对象进行操做。
static
被声明为static的函数标识符具备内部连接,换句话说,别的翻译单元没法使用所声明的函数标识符来访问该函数。
被声明为static的对象标识符可能为外部连接,也可能为内部连接,至因而哪种连接形式,取决于对象的定义是在函数内仍是函数外。被声明为static的对象具备静态存储周期。所以,修饰符static容许定义局部对象(也就是具备语句块做用域的对象)为具备静态的存储周期。
extern
被声明为extern的函数和对象标识符具备外部连接。能够在程序中任何地方使用这些标识符。外部对象具备静态的存储周期。
_Thread_local
修饰符_Thread_local声明对象为线程局部(thread-local),表示每一个线程都分别具备该对象的实例。只有对象能被声明为线程局部,而函数不能。若是在函数内部声明一个线程局部对象,声明必须具备修饰符extern或static。在一个表达式中,线程局部对象的标识符引用当前线程中对象的本地实例,当前线程指当前计算该表达式的线程。示例请参见14.4.1节。数组

类型限定符函数

能够利用类型限定符修改声明中的类型,类型限定符有const、volatile、restrict和_Atomic。声明中可以使用多个类型限定符,它们的顺序没有限制。类型限定符列表内能够屡次出现相同的类型限定符,或者经过限定typedef名称的方式,反复使用同一个限定符。编译器会忽略重复出现的限定符,将它们视为只出现一次。
各类类型限定符的含义以下:
const
对象的类型若是采用了限定符const,则该对象就是常量。在定义该对象以后,程序没法修改它。
volatile
对象的类型若是采用了限定符volatile,则该对象能够被其余进程或事件修改。关键字volatile告诉编译器在每次使用该对象值时,都要从新读取它,即使程序自己自上一次获取后再没有修改过它的值。这种限定符一般用于硬件接口编程,以防止变量值被外部事件修改后,未能及时更新。
restrict
限定符restrict只适用于对象指针类型。这种类型限定符是C99新增长的,用来告诉编译器,一个被指针所引用的对象,若是它能够被修改,那么只能被restrict限定的指针修改,不能被除该指针之外的其余任何方式修改,不管是直接方式仍是间接方式。该特性容许编译器采用特定优化技术,而该技术可能须要restrict特性的支撑。编译器也有可能会忽略限定符restrict,而不对程序结果形成任何影响。
_Atomic
采用类型限定符_Atomic声明的对象是一个原子对象(atomic object)。数组不能是原子对象。对原子对象的支持是可选的:C11实现版本中,若是定义了宏_STDC_NO_ATOMICS_,则表示程序不能声明原子对象。关于原子对象的详细介绍,请参见第14章。
编译器也能够将const对象存储在内存中的只读区域,可是volatile对象不能。若是程序不使用volatile对象的地址,也有可能编译器干脆不为该对象分配内存。
对象若是同时使用了限定符const和volatile,以下例中ticks对象所示,它不能被程序自己修改,但能够被其余事件修改,例如时钟芯片的中断处理程序:
extern const volatile int ticks;优化

相关文章
相关标签/搜索