尽管大多数人可能理解变量或函数的“声明”与“定义”之间的区别,但是为了完整起见,我想对其进行澄清。
声明变量或函数仅声明变量或函数存在于程序中的某个位置,但未为它们分配内存。变量或函数的声明起着重要的作用-告诉程序其类型将是什么。如果是函数声明,它还会告诉程序参数,其数据类型,这些参数的顺序以及函数的返回类型。这就是声明。
关于定义,当我们定义一个变量或函数时,除了声明所做的一切外,它还为该变量或函数分配内存。因此,我们可以将定义视为声明的超集(或声明作为定义的子集)。
变量或函数可以声明多次,但只能定义一次。(请记住基本原则,即不能有两个位置具有相同的变量或函数)。
由于extern关键字将功能的可见性扩展到整个程序,因此该功能可以在整个程序的任何文件中的任何位置使用(调用),只要这些文件包含该功能的声明即可。(在适当的位置声明了函数,编译器知道该函数的定义存在于其他地方,并且可以继续编译文件)。这就是extern功能。
我们经常会遇到这样的问题,我们的函数在调用之后定义的,那么我们程序是不知道这个函数的存在的,也就导致这函数无法使用比如:
解决办法我们可以在文件开头对函数进行声明
extern还可以配合头文件将文件内需要的变量或函数结构体等声明出来提供给其它功能使用
在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,前面我们已经看过 stdio.h 头文件,它是编译器自带的头文件,引用头文件相当于复制头文件的内容。
头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享。
有两种类型的头文件:程序员编写的头文件和C标准库自带的头文件 ,在程序中要使用头文件,需要使用 C预处理指令 #include来引用它
#include 的处理过程很简单,就是将头文件的内容插入到该命令所在的位置,从而把头文件和当前源文件连接成一个源文件,这与复制粘贴的效果相同。但是我们不会直接在源文件中复制头文件的内容,因为这么做很容易出错,特别在程序是由多个源文件组成的时候。
建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件
源文件的名字 可以不和头文件一样,但是为了好管理,一般头文件名和源文件名一样.
一个 #include 命令只能包含一个头文件,多个头文件需要多个 #include 命令
不管是标准头文件,还是自定义头文件,都只能包含变量和函数的声明,不 能包含定义,否则在多次引入时会引起重复定义错误(!!!)
如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误。为了防止这种情况,标准的做法是把文件的整个内容放在条件编译语句中,如下:
#ifndef 头文件名 //头文件名的格式为"_头文件名_",注意要大写
#define 头文件名
头文件内容
#endif
示例代码:头文件test.h
#ifndef _MAIN_H_ //如果没有定义头文件main.h,则执行下面的代码。这是防止重复定义
#define _MAIN_H_ //定义头文件
//下面的代码是头文件的内容
#include //头文件
#define ADD 1 //宏定义
extern int x; //全局变量
void swap(int a, int b);//函数声明
#endif //表示头文件结束
注意事项: 在头文件中声明变量必须需要加extern因为extern声明告诉编译器这个变量的定义在其他文件中,我在这里只是声明不使用,所以并不会为它分配内存。 而函数默认就有extern所以无须手动声明
引用头文件的语法它的形式有以下两种:
#include
这种形式用于引用系统头文件。它在系统目录的标准列表中搜索名为 file 的文件。
#include "file"
这种形式用于引用用户头文件。它在包含当前文件的目录中搜索名为 file 的文件。
如果一个结构体或共用体等, 会在多个文件中使用那么我们会将他定义在头文件中,这样就可以通用了