1.多个源代码文件
多个 .c 文件
main() 里的代码太长了,适合分成几个函数(把相应功能剥离出来放在函数里头);
一个源代码文件太长了适合分成几个文件(函数拿出来放到多个 .c 文件里头);
两个独立的源代码文件不能编译形成可执行的程序。
编译单元
一个 .c 文件是一个编译单元。
编译器每次编译只处理一个编译单元。
一个项目对应产生一个可执行文件,IDE:集成开发环境
2.头文件
把函数原型(声明)放到一个头文件(以 .h 结尾)中,在需要调用这个函数的源代码文件(.c 文件)中 #include 这个头文件,就能让编译器在编译时知道函数的原型(形成桥梁/合同)。
#include
#include 是一个编译预处理指令,和宏一样,在编译之前就处理了。
它把那个文件的全部文本内容原封不动地插入到它所在的地方。所以也不是一定要在 .c 文件的最前面 #include 。
" " 还是 < >
#include 有两种形式来指出要插入的文件。
" " 要求编译器首先在当前目录(.c 文件所在的目录)寻找这个文件,如果没有,到编译器指定的目录去找;
< > 让编译器只在指定的目录去找。
编译器知道自己的标准库的头文件在哪里。
自己的头文件用 " " ,标准库的头文件用 < > 。
3. #include 的误区
#include 不是用来引入库的(把内容原封不动地插入到所在的地方)。
#include <stdio.h> 只是为了让编译器知道 printf 函数的原型。保证你调用时给出的参数是正确的类型。
头文件 TIPS
在使用和定义这个函数的地方都应该 #include 这个头文件。
一般的做法就是任何 .c 都有对应的同名的 .h 。把所有对外公开的函数的原型和全局变量的声明都放进去。(全局变量可在多个 .c 之间共享)
不对外公开的函数
在函数前加上 static 就使得它成为只能在所在的编译单元中被使用的函数。
在全局变量前面加上 static 就使得它成为只能在所在的编译单元中被使用的全局变量。
4.声明和定义
int i; 变量的定义 extern int i; (在头文件中)是变量的声明,不能初始化。
声明是不产生代码的东西,只记下来。
函数原型(声明) 变量声明 结构声明 宏声明 枚举声明 类型声明(typedef) inline 函数
定义是产生代码的东西。(函数 全局变量)
5.头文件
只有声明可以被放在头文件中。(是规则不是法律)
否则会造成一个项目中多个编译单元里有重名的实体。
重复声明
同一个编译单元(.c)里,不能让一个结构的声明出现两次。
如果你的头文件里有结构的声明,这个头文件很难不会在一个编译单元里被 #include 多次。
所以需要 “标准头文件结构”。
6.标准头文件结构
下划线__LIST_HEAD__是为了保证不和正常的宏定义重复。
#ifndef 为条件编译指令。如果已经定义过不会再被编译,避免头文件里有重复引用的情况。
网友评论