7.10 关于变量的声明和定义
在第2章中介绍了如何定义一个变量。在本章中又介绍了如何对一个变量作声明。可能有些读者弄不清楚定义与声明有什么区别,它们是否是一回事。有人认为声明就是定义,有人认为只有赋了值的才是定义。在C语言的学习中,关于定义与声明这两个名词的使用上始终存在着混淆。不仅许多初学者没有搞清楚,连不少介绍C语言的教材也没有给出准确的介绍。
从第2章已经知道,一个函数一般由两部分组成:声明部分和执行语句。声明部分的作用是对有关的标识符(如变量、函数、结构体、共用体等)的属性进行声明。对于函数而言声明和定义的区别是明显的,在本章7.4节中已说明,函数的声明是函数的原型,而函数的定义是对函数功能的定义。对被调用函数的声明是放在主调函数的声明部分中的,而函数的定义显然不在声明部分的范围内,它是一个独立的模块。
对变量而言,声明与定义的关系稍微复杂一些。在声明部分出现的变量有两种情况:一种是需要建立存储空间的(如“int a;
”),另一种是不需要建立存储空间的(如“extern int a;
”)。前者称为定义性声明(defining declaration),或简称定义(definition);后者称为引用性声明(referencing declaration)。广义地说,声明包括定义,但并非所有的声明都是定义。对“int a;
”而言,它既是声明,又是定义;而对“extern int a;
”而言,它是声明而不是定义。一般为了叙述方便,把建立存储空间的声明称定义,而把不需要建立存储空间的声明称为声明。
显然这里指的声明是狭义的,即非定义性声明。例如:
int main() {
extern int A; // 声明,不是定义。声明将已定义的外部变量 A 的作用域扩展到此
// ...
return 0;
}
int A; // 定义,定义 A 为整型外部变量
外部变量定义和外部变量声明的含义是不同的。外部变量的定义只能有一次,它的位置在所有函数之外。在同一文件中,可以有多次对同一外部变量的声明,它的位置可以在函数之内(哪个函数要用就在哪个函数中声明),也可以在函数之外。系统根据外部变量的定义(而不是根据外部变量的声明)分配存储单元。对外部变量的初始化只能在“定义”时进行,而不能在“声明”中进行。所谓“声明”,其作用是声明该变量是一个已在其他地方已定义的外部变量,仅仅是为了扩展该变量的作用范围而作的“声明”。
注: 有一个简单的结论,在函数中出现的对变量的声明(除了用 extern
声明的以外)都是定义。在函数中对其他函数的声明不是函数的定义。
例子:变量的声明和定义
编写程序:
#include <stdio.h>
// 定义外部变量 A
int A = 10;
void func();
int main() {
extern int A; // 声明外部变量 A
printf("In main: A = %d\n", A);
func();
return 0;
}
void func() {
extern int A; // 声明外部变量 A
printf("In func: A = %d\n", A);
}
程序分析:
- 外部变量
A
在文件开头被定义,初始化为 10。 - 在
main
函数和func
函数中都用extern
声明了外部变量A
,扩展了A
的作用域,使得这两个函数可以引用全局变量A
。 printf
函数输出A
的值为 10。
运行结果:
In main: A = 10
In func: A = 10
这个例子说明了如何通过 extern
声明在不同函数中引用同一个外部变量 A
。
小结
- 定义 是为变量或函数分配存储空间,并且可以初始化。
- 声明 是说明变量或函数的存在和类型,但不分配存储空间。
对于外部变量,定义只能有一次,而声明可以有多次。声明的作用是扩展变量的作用域,使其在其他函数或文件中可以引用该变量。