走马观花ANSI C标准-标识符
标识符(identifier)
1、一个标识符可以表示:
a) 对象(object)
b) 函数(function)
c) 结构体(struct)的标签(Tag)[注1]
d) 结构体的成员
e) 联合体(union)或枚举类型(enumeration)
f) 类型别名(typedef)
g) 标签(label)
h) 宏(macro)
i) 宏参数(macro parameter)
同一个标识符在程序的“不同点”处可以表示不同的“实体”(entity)。[注2]
一个枚举(enumeration)的成员被称为一个“枚举常量,enumeration constant”。
2、作用域(Scope)
Scope共定义了四种:
a) 函数作用域(function)
b) 文件作用域(file)
c) 块作用域(block)
d) 函数原型作用域(function prototype)
标签名(label name)是唯一一个拥有“函数作用域”的标识符。它可以用在它所在函数内的任何位置。
标识符拥有的作用域取决于它声明时的位置。
如果标示符声明在任何块(block)或者函数定义的参数列表外的话,那么它拥有“文件作用域”,它的作用域同所在“翻译单元”;
如果标示符声明在任何块(block)或者函数定义的参数列表内的话,那么它拥有“块作用域”,它的作用域同所在“块”;
如果标示符声明在函数原型的参数列表内的话,那么它拥有“函数原型作用域”,它的作用域同所在的“函数原型”。
一个原则:“内层作用域,inner scope”的标识符会隐藏(hide)“外层作用域,outer scope”的标识符。
3、标识符的链接(linkages of identifiers)
在不同Scopes或者同一个Scope下声明不止一次的标识符,进程会将它们参考到(refer to)同一个object或function,这就被称为“linkage”。注意:在不同的标识符之间没有linkage可言。
标准定义了3种linkage:
a) external
b) interal
c) none
1) 在组成一个完整程序的“翻译单元”和“库”中,拥有external linkage的标识符指示同一个object or function;
2) 在一个“翻译单元”内,拥有internal linkage的标识符指示同一个object or function;
3) 一个“文件作用域”的标识符,如果前面有“static”修饰,那么该标识符拥有“internal linkage”;
4) 一个没有任何存储类型(storage-class)修饰的函数标识符与使用extern修饰的函数标识符的linkage相同;
5) none linkage情况:
a) 一个被声明为既不是object又不是function的标识符;
b) 一个被声明为函数parameter的标识符;
c) 一个被声明为object,拥有block scope,但无extern修饰的标识符。
[注1]
关于“结构体的标签”我们举例说明:
struct point_t {
int x;
int y;
};
point_t被称为“结构体的标签”,注意在ANSI C中“结构体的标签”不是类型,不能单独使用。必须和struct联合使用。
如:point_t origin; /* error */
struct point_t origin; /* ok */
[注2]
关于这句话“同一个标识符在程序的“不同点”处可以表示不同的“实体”(entity)”还是很好理解的。一般都是由于Scope的不同。例如:
src1.c中的static int count和src2.c中的同名的static int count。
评论