标识符(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。

© 2005, bigwhite. 版权所有.

Related posts:

  1. 走马观花ANSI C标准-介绍
  2. 走马观花ANSI C标准-环境
  3. Advanced CVS
  4. Effective Java阅读笔记-item异常
  5. 同步问题讨论-Tony与Alex的对话系列