一、头文件
头文件就是对用户的说明。函数,参数,共享变量,各种各样的接口的说明。提高程序的可读性。
头文件对计算机而言没什么作用,它只是在预编译时在#include的地方展开一下,没别的意义了,其实头文件主要是给别人看的。我做过一个实验,将头文件的后缀改成xxx.txt,然后在引用该头文件的地方用#include"xxx.txt"
编译,链接都很顺利的过去了,由此可知,头文件仅仅为阅读代码作用,没其它的作用了!
二、声明和定义[钱能:C++程序设计教程,C++ primer]
声明:声明语句声明某个名称。因为有了名称,在后续的语句中才可以使用。但若要能真正运行,还必须在适当地方提供该名称的定义。它是用于向程序表明变量的类型和名字。没分配存储空间。
定义:定义语句不但声明了名称,而且还给名称分配了存储空间,使之成为一个能够存放数据的实体。
什么时候是声明?什么时候是定义?如何判断?
这里先要讲到一个关键词:extern[谭浩强:C程序设计(第二版)]
用extern声明外部变量(即全局变量)
外部变量是在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的结尾。在此作用域内,全局变量可以为程序中的各个函数所引用。编译时将外部变量分配在静态存储区。
有时候需要用extern来声明外部变量,以扩展外部变量的作用域。
1)在一个文件内声明外部变量void main()
{
extern int a, b;
printf("%d,%d\n",a,b);
}
int a=1, b=2; |
如果main函数中的定义前不加extern,程序就会出错。因为外部变量定义在main之后。
2)在多文件的程序中声明外部变量//file1.c
int a;
void main()
{
...
}
//file2.c
extern int a;
...
|
用extern声明外部变量时,类型名可以写也可以省略。如file2.c中的extern int a;可写为extern a;
extern只用作声明,而不用于定义。
变量声明
extern int a; //声明一个全局变量a
int a; //定义一个全局变量a
变量可以多次声明,但只能定义一次。
函数声明
对于函数也一样,也是定义和声明,定义的时候用extern,说明这个函数是可以被外部引用的,声明的时候用extern说明这是一个声明。 但由于函数的定义和声明是有区别的,定义函数要有函数体,声明函数没有函数体,所以函数定义和声明时都可以将extern省略掉,反正其他文件也是知道这个函数是在其他地方定义的,所以不加extern也行。两者如此不同,所以省略了extern也不会有问题。
用一个例子来说明。
//hoo.h
int h; //定义
//goo.h
#include "hoo.h"
//foo.h
#include "hoo.h"
//goo.cpp 空
//hoo.cpp 空
//foo.cpp
#include "iostream.h"
#include "foo.h"
#include "goo.h"
#include "hoo.h"
void main()
{
h = 0;
} |
--------------------Configuration: Prove - Win32 Debug--------------------
Compiling...
foo.cpp
d:\mycode\vc++\prove\hoo.h(3) : error C2086: 'h' : redefinition
d:\mycode\vc++\prove\hoo.h(3) : error C2086: 'h' : redefinition
Error executing cl.exe.
Creating browse info file...
Prove.exe - 2 error(s), 0 warning(s) |
这时会产生错误:redefinition,重复定义
因为在foo.cpp中#include "foo.h" // 包含int h;
#include "goo.h" // 包含int h;
#include "hoo.h" // 包含int h; |
这就说明:当一个头文件中定一个变量时,如果它被多次包含就会出现重复定义的错误。
所以:千万不要在头文件中定义变量
解决上面的错误可以有两种方法。
1)#ifndef ... #define ... #endif
将hoo.h修改如下:#ifndef _HOO_H_
#define _HOO_H_
int h;
#endif |
就不出现错误。
//2010.6.18
上面说不会产生错误,是不对的。是因我在没有.cpp文件中加入hoo.h文件,如果多外.cpp文件包含hoo.h文件。比如,我在goo.cpp中加入语句:#include "hoo.h",则会出现如下错误:
goo.obj : error LNK2005: "int h" (?h@@3HA) already defined in foo.obj |
//故在头文件中绝不能定义变量!
2)将定义改为声明。int h;改为 extern int h;
这样,在其它文件中只要而且只能定义一次,就可以在各个文件中共享此变量。这就是说:
变量可以多此声明,而只能定义一次。
总结[网上]
a.头文件(.h)中是对于该模块接口的声明,接口包括该模块提供给其它模块调用的外部函数及外部全局变量,对这些变量和函数都需在.h中文件中冠以extern关键字声明;(函数前可以省略)
b.永远不要在.h文件中定义变量;(应该声明)
c.如果要用其它模块定义的变量和函数,直接包含其头文件即可。(变量还需再次定义)