|
注:以下内容为本人查阅资料整理,并非权威且难免出错,如果有异议欢迎讨论,并且以下内容并不全面,欢迎补充。
要弄清楚这个问题,先要复习几个基本概念,由于C语言中声明和定义的概念涉及的比较广,本文仅限于讨论变量的声明和定义以及相关的基本知识。
翻译单元:源文件经过预处理后的结果。
概念1. 变量的作用域
作用域定义了变量的可见性,共有四种作用域:
(1)函数作用域:只有一种情况,就是函数内的标号,goto语句使用的那个标号,它具有函数作用域,如果在函数内有一个标号,则在整个函数的任何位置都可以访问。(这个与变量的讨论无关)。
(2)文件作用域:如果一个变量的声明不在任何块以及函数参数列表内,则该变量具有文件作用域。
(3)块作用域:如果一个变量声明在块内或者声明在函数定义的参数列表中,则该变量具有块作用域。
(4)函数原型作用域:函数声明的参数列表中的变量声明,具有函数原型作用域。
概念2. 变量的连接类型
在同一个作用域或者不同作用域对一个变量的多次声明被引用到同一变量的过程叫做连接。连接分为三类:
(1)内部连接:变量声明具有文件作用域且由static存储类型修饰的变量为内部连接类型。
(2)外部连接:变量声明具有文件作用域并且没有static存储类型修饰,则该变量为外部连接。
(3)没有连接:函数的参数;块作用域中未用extern存储修饰符的变量
使用extern修饰的变量声明,如果此声明之前有对此变量的声明,则其连接方式与前一个声明相同,如果此声明前没有此变量的其他声明,则此声明为外部连接。
内部连接可以连接到翻译单元内部(相当于同一个源文件内)的变量,外部连接可以连接到整个工程的所有翻译单元以及库中的变量。
如果一个变量没有连接,则在同一个作用域或者命名空间中对此变量的声明不能超过1次。(此规则可以解释局部变量的声明不能多于1个,局部变量没有连接功能,所以多个声明是非法的)
概念3. 外部定义
在函数外面的声明(具有文件作用域)叫做外部声明。
包含初始化的外部声明叫做外部定义。(由此可得出外部定义是外部声明的子集)
外部定义最多只能有一个。
如果一个变量声明具有文件作用域且未被初始化,且未使用存储修饰符或者使用static修饰符,则该声明为不确定的定义(tentative definition)
如果一个翻译单元包含一个或者多个不确定的定义,并且不包该变量的外部定义,则其行为相当于在翻译单元的结尾增加了一个具有文件作用域的相应的类型的并且初始化为0的变量声明。
在同一个作用域内对同一个变量的声明必须具有兼容的数据类型:
假定unsigned char与uint8_t类型是兼容的则:
- unsigned char a;
- uint8_t a; //合法
- int b;
- double b; //不合法
复制代码
- int i1 = 1; // definition, external linkage
- static int i2 = 2; // definition, internal linkage
- extern int i3 = 3; // definition, external linkage
- int i4; // tentative definition, external linkage
- static int i5; // tentative definition, internal linkage
- int i1; // valid tentative definition, refers to pre vious
- int i2; // 6.2.2 renders undefined, linkage disagreement
- int i3; // valid tentative definition, refers to pre vious
- int i4; // valid tentative definition, refers to pre vious
- int i5; // 6.2.2 renders undefined, linkage disagreement
- extern int i1; // refers to pre vious, whose linkage is external
- extern int i2; // refers to pre vious, whose linkage is internal
- extern int i3; // refers to pre vious, whose linkage is external
- extern int i4; // refers to pre vious, whose linkage is external
- extern int i5; // refers to pre vious, whose linkage is internal
复制代码
|
赞赏
-
1
查看全部赞赏
-
|