C语言中的定义和声明的区别

时间:2021-04-14 16:47:48

变量的定义用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且仅有一个定义。

声明用于向程序表明变量的类型和名字定义包括声明:当定义变量时我们声明了它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。不定义变量的声明包括对象名、对象类型前的关键字extern。

extern int i; // declares but does not define i

int i; // delares and defines i

例子:

1 #include <stdio.h>
2
3 intmain()
4 {
5 extern int i;
6 i = 5;
7 return 0;
8}
VS2010:  error LNK2001: 无法解析的外部符号 "int i" (?i@@3HA)

           fatal error LNK1120: 个无法解析的外部命令

分析:extern int i只是说明变量定义在程序的其他地方(也就是程序的外部,一般是在程序的其他文件中),但是程序找不到该变量,正确使用如下:为项目再添加一个.c的源文件,在该源文件中添加定义int i,这样就可以正确使用。

extern声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明多次,但只能定义一次

只有当声明也是定义时,声明才可以有初始化式,因为只有定义才分配存储空间。初始化式必须要有存储空间来进行初始化。如果声明有初始化式,那么它可以当作定义,即使声明标记为extern:

extern double pi 3.1416; //definition

1 #include <stdio.h>
2
3 extern int i = 5;
4 int main()
5 {
6
7 printf("i %d\n"i);
8 return 0;
9 }

编译通过。虽然使用了extern, 但是这条语句还是定义了pi,分配并初始化了存储空间。只有当extern声明位于函数外部时,才可以含有初始化式

例子:

1 #include <stdio.h>
2
3 intmain()
4 {
5 externinti=5// 在函数内部使用externt 并初始化。编译时出错:error C2205: “i”: 不能对带有块范围的外部变量进行初始化
6 printf("i = %d\n", i);
7 return0;
8 }

编译时出错:error C2205: i不能对带有块范围的外部变量进行初始化

 

因为已初始化的extern声明被当作是定义,所以该变量任何随后的定义都是错误的:

extern double ip 3.1416; //definition

double pi 3.1416; //error: redefinition of pi

例如:

1 #include <stdio.h>
2
3 externdoublepi=3.1416; //definition
4 doublepi=3.1416; // error C2374: pi: 重定义;多次初始化
5 intmain()
6 {
7 printf("pi = %f\n", pi);
8 return0;
9 }

编译出错:error C2374: “pi”: 重定义;多次初始化,

但是要注意区别:

1 #include <stdio.h>
2
3 extern double pi = 3.1416//definition
4 int main()
5 {
6 double pi = 3.1415// definition, and no error,output pi = 3.141500, not pi = 3.141600
7 printf("pi = %f\n", pi);
8 return 0;
9 }

分析:这涉及到作用域问题,double pi 3.1415具有main(){}内部作用域,

而extern double pi 3.1416具有全局变量作用域,在执行main(){}过程中,man(){}内部的那个pi(pi 3.1415)覆盖了全局变量pi(pi 3.1416)。因此没有变量pi的重定义的错误,输出结果为pi 3.1415;

同样,随后的含有初始化式的extern声明也是错误的:

extern double pi 3.1416; // definition

extern double pi; // OK: declaration not definition

extern double pi 3.1416; // error: redefinition of pi

extern应用场合:任何在多个文件中使用的变量都需要有与定义分离的声明。这种情况下,一个文件含有变量的定义,使用该变量的其他文件则包含该变量的声明(而不是定义),因为变量须且仅能定义一次,而变量的声明可以多次。

-----摘自《c++ primer 4th》