⼤程序
多个.c⽂件
• main()⾥的代码太⻓了适合分成⼏个函数
• ⼀个源代码⽂件太⻓了适合分成⼏个⽂件
• 两个独⽴的源代码⽂件不能编译形成可执⾏的程序
编译单元
• ⼀个.c⽂件是⼀个编译单元
• 编译器每次编译只处理⼀个编译单元
项⺫
• 在Dev C++中新建⼀个项⺫,然后把⼏个源代码⽂件
加⼊进去
• 对于项⺫,Dev C++的编译会把⼀个项⺫中所有的源
代码⽂件都编译后,链接起来
• 有的IDE有分开的编译和构建两个按钮,前者是对单
个源代码⽂件编译,后者是对整个项⺫做链接
头⽂件
函数原型
• 如果不给出函数原型,编译器会猜测你所调⽤的函数
的所有参数都是int ,返回类型也是int
• 编译器在编译的时候只看当前的⼀个编译单元,它不
会去看同⼀个项⺫中的其他编译单元以找出那个函数
的原型
• 如果你的函数并⾮如此,程序链接的时候不会出错
• 但是执⾏的时候就不对了
• 所以需要在调⽤函数的地⽅给出函数的原型,以告诉
编译器那个函数究竟⻓什么样
头⽂件
• 把函数原型放到⼀个头⽂件(以.h结尾)中,在需要
调⽤这个函数的源代码⽂件(.c⽂件)中#include这
个头⽂件,就能让编译器在编译的时候知道函数的原
型
#include
• #include是⼀个编译预处理指令,和宏⼀样,在编译
之前就处理了
• 它把那个⽂件的全部⽂本内容原封不动地插⼊到它所
在的地⽅
• 所以也不是⼀定要在.c⽂件的最前⾯#include
“”还是<>
• #include有两种形式来指出要插⼊的⽂件
• “”要求编译器⾸先在当前⺫录(.c⽂件所在的⺫录)
寻找这个⽂件,如果没有,到编译器指定的⺫录去
找
• <>让编译器只在指定的⺫录去找
• 编译器⾃⼰知道⾃⼰的标准库的头⽂件在哪⾥
• 环境变量和编译器命令⾏参数也可以指定寻找头⽂件
的⺫录
#include的误区
• #include不是⽤来引⼊库的
• stdio.h⾥只有printf的原型,printf的代码在另外的地
⽅,某个.lib(Windows)或.a(Unix)中
• 现在的C语⾔编译器默认会引⼊所有的标准库
• #include 只是为了让编译器知道printf函数
的原型,保证你调⽤时给出的参数值是正确的类型
头⽂件
• 在使⽤和定义这个函数的地⽅都应该#include这个头
⽂件
• ⼀般的做法就是任何.c都有对应的同名的.h ,把所有
对外公开的函数的原型和全局变量的声明都放进去
不对外公开的函数
• 在函数前⾯加上static就使得它成为只能在所在的编
译单元中被使⽤的函数
• 在全局变量前⾯加上static就使得它成为只能在所在
的编译单元中被使⽤的全局变量
声明
变量的声明
• int i;是变量的定义
• extern int i;是变量的声明
声明和定义
• 声明是不产⽣代码的东⻄
• 函数原型
• 变量声明
• 结构声明
• 宏声明
• 枚举声明
• 类型声明
• inline函数
• 定义是产⽣代码的东⻄
头⽂件
• 只有声明可以被放在头⽂件中
• 是规则不是法律
• 否则会造成⼀个项⺫中多个编译单元⾥有重名的实体
• *某些编译器允许⼏个编译单元中存在同名的函数,
或者⽤weak修饰符来强调这种存在
重复声明
• 同