举个简单的例子!你会容易理解的。
你写一个stack.h的头文件,里面声明几个函数原形:
stack.h
#ifndef STACK_H
#define STACK_H
extern void push(char);
extern char pop(void);
extern int is_empty(void);
#endif
你能够在其相应的stack.c中对这些函数进行实现
stack.c
#include "stack.h"
void push(char)
{
/*your code*/
}
char pop(void)
{
/*your code*/
}
int is_empty(void)
{
/*your code*/
}
在main.c中你能够这样写
#include <stdio.h>
#include "stack.h"
int main()
{
push('a');
push('b');
push('c');
while(!is_empty())
putchar(pop());
putchar('\n');
return 0;
}
大体格式就是这样,在stack.h(这个名字你能够随便定),在这个头文件中声明函数原形,在相应的stack.c中进行函数定义与实现,主程序文件中包含这个头文件以后就能够调用stack.h中声明的函数,编译后无错误便可执行,程序员
在咱们语言的初学阶段,每每咱们的程序只有一个.c的文件或这不多的几个,这时咱们就不多遇到头文件组织这个头疼的问题,随着咱们程序的增长,代码 量到了几千行甚至几万行,文件数也愈来愈多。这时这些文件的组织就成了一个问题,其实说白了这些文件的组织问题从理论上来讲是软件工程中的模块设计等等的问题。函数
由上能够看出,.h文件最初就是用来给变量和函数提供一些全局性的声明,这些声明被其余.c文件共享,方便变量和声明的修改,使得大型代码逻辑更清晰更易于维护。所以.h文件中通常是声明,不多有代码的具体实现。那么为何在.h文件中实现函数也不会出错呢?在.h文件中实现函数与在.c文件中实现函数有什么区别和联系呢?普通的.C文件和包含main函数的c文件有什么区别和联系呢?编码
要解决上述问题,首先必须弄清编译器的工做原理。编译器的最终目的是将程序员编写的源代码转换成机器可以识别运行的二进制机器码。大致上分,能够分为4个步骤:翻译
1.头文件的预编译,预处理设计
编译器在编译源代码时,会先编译头文件,保证每一个头文件只被编译一次。3d
在预处理阶段,编译器将c文件中引用的头文件中的内容所有写到c文件中。code
2.词法和语法分析(查错)get
3.编译(汇编代码)编译器
转化为汇编码,这种文件称为目标文件。io
4.连接(二进制机器码)
将汇编代码转换为机器码,生成可执行文件。
在编译过程当中,.h文件中的全部内容会被写到包含它的.c文件中,而全部的.c文件以一个共同的main函数做为可执行程序的入口。所以,在.h文件中编写函数实现并不会出错,至关于全部.h的内容最后都被写到了main.c文件中。可是为了逻辑性、易于维护性以及一些其余目的(可参考c语言中.h文件和.c文件的解析 ),通常在.h文件中写函数的声明,在.c文件中编写函数的实现。
预编译
伪指令特殊符号处理
编译
默认获得二进制 ,可是按步骤是获得汇编代码。
汇编
把汇编代码翻译成机器码 。一般把编译和汇编合成一个编译 ,将通过预处理后的源文件经过编译获得机器码 ,目标文件
连接
将多个库文件,目标文件对接 ,生成可执行文件
声明:本文中如出现侵权文字,请留言