700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C语言基础5-预编译部分知识(#include+.h文件和.c文件的区别

C语言基础5-预编译部分知识(#include+.h文件和.c文件的区别

时间:2020-07-19 23:04:54

相关推荐

C语言基础5-预编译部分知识(#include+.h文件和.c文件的区别

main()

一个C程序以一个名为mian()的函数为开始进行执行。C程序所有的文件和依赖库都被编译到一个程序文件内,这个程序文件内只能包含一个main()程序。操作系统使用这个main函数来作为程序的起始。Main()会返回一个整型值,通常这个程序正常执行时这个整型值为0,如果这个值非0,说明程序在执行时遇到了一些错误情况。

函数原型(prototype)

一个函数的”原型“是指定义了函数名和函数变量,但是没有定义程序体。如果我们想要一个在任意文件内的调用者都可以使用某个函数,那我们就需要让这个调用者”看到“这个函数的原型。举例来讲,下面就是一个Twice()函数和Swap()函数的原型。函数体是空缺的,因此这个原型定义以分号;结尾

int Twice(int num);void Swap(int* a, int* b);

在ANSI C中:

一个函数可以被声明为static,在这种情况下,它只能被在它定义处后面的语句使用,且只能在定义的文件内使用。使用静态的函数是不需要声明原型的(我们可以将static函数定义在程序的开始处),这会减少我们的工作量

//待补充

预处理

在C源文件被提交给编译器前,会进行预处理步骤,两个和预处理有关的最常用的C指令是#define和#include

#define

#define MAX 100

#include

#include

.h文件和.c文件

一个C语言的传统是,对于一个包含多个函数的"foo.c"文件来说:

会有一个额外的"foo.h"文件包含着"foo.c"的函数原型,这些函数可能在其他地方被调用。"foo.c"的一些只会被内部使用的函数,应该被声明为static。在"foo.c"文件的顶部应该包含这样一个指令#include "foo.h"任意一个"xxx.c"文件,如果希望调用"foo.c"中的函数,必须通过这样一个指令进行声明#include "foo.h"

但是理论上来说c文件与h文件里的内容,只要是c语言所支持的,无论写什么都可以,比如在h文件中写函数体,只要在任何一个C文件包含此.h文件就可以将这个函数编译成目标文件的一部分(编译是以C文件为单位的,如果不在任何C文件中包含此.h文件的话,这段代码就形同虚设),我们可以在C文件中进行函数声明,变量声明,结构体声明,这也是被允许的。那为何要分成h文件与c文件呢?又为何一般都在h文件中进行函数、变量、宏和结构体声明,而在c文件中去进行变量定义,函数实现呢?原因有下面几个:

如果在h文件中实现一个函数体,那么如果在多个c文件中引用它,而且又同时编译多个c文件,将其生成的目标文件连接成一个可执行文件,在每个引用此h文件的c文件所生成的目标文件中,都有一份这个函数的代码,如果这段函数又没有定义成局部函数,那么在连接时,就会发现多个相同的函数,就会报错如果在h文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此h文件的C文件中同样存在相同变量名的拷贝,关键是此变量被赋了初值,所以编 译器就会将此变量放入DATA段,最终在连接阶段,会在DATA段中存在多个相同的变量,它无法将这些变量统一成一个变量,也就是仅为此变量分配一个空 间,而不是多份空间,假定这个变量在h文件没有赋初值,编译器就会将之放入BSS段,连接器会对BSS段的多个同名变量仅分配一个存储空间如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相应的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声 明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就 只需要引用一个就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一下h文件就行了

其实,从C编译器角度看,.h和.c皆是浮云,就是改名为.txt、.doc也没有大的分别。换句话说,就是.h和.c没啥必然联系。.h中一般放的是同名.c文件中定义的变量、数组、函数的声明,需要让.c外部使用的声明。这个声明有啥用?只是让需要用这些声明的地方方便引用。因为#include “xx.h” 这个宏其实际意思就是把当前这一行删掉,把xx.h 中的内容原封不动的插入在当前行的位置。由于想写这些函数声明的地方非常多(每一个调用xx.c 中函数的地方,都要在使用前声明一下子),所以用#include “xx.h” 这个宏就简化了许多行代码——让预处理器自己替换好了。也就是说,xx.h 其实只是让需要写xx.c 中函数声明的地方调用(可以少写几行字),至于include 这个.h 文件是谁,是.h 还是.c,还是与这个.h 同名的.c,都没有任何必然关系。

这样你可能会说:啊?那我平时只想调用xx.c 中的某个函数,却include了xx.h 文件,岂不是宏替换后出现了很多无用的声明?没错,确实引入了很多垃圾 ,但是它却省了你不少笔墨,并且整个版面也看起来清爽的多。鱼与熊掌不可得兼,就是这个道理。反正多些声明(.h一般只用来放声明,而放不定义,参见拙著“过马路,左右看”)也无害处,又不会影响编译,何乐而不为呢?

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。