6.3 大程序结构
1.多个 .c文件,如何编译
main()里的代码太长,适合分成几个函数 一个源代码文件太长,适合分成几个文件 两个独立的源代码文件 不能编译成一个可执行程序之前我们写的代码,是放在一个.c文件中,如果main写在一个.c文件中,max()写在一个.c文件中呢?
2.项目
新建项目: Devcpp中 文件 —— 新建 —— 项目 —— Console application 对于项目,Devcpp 的编译会把一个项目中的所有源代码文件都编译后,链接起来 有的IDE有 编译 和 构建 两个按钮,编译 是对单个源代码文件编译,构建是对整个项目做链接3.编译单元
一个.c文件就是一个编译单元 编译器每次编译只处理一个编译单元4.头文件
把函数原型 放到一个 以.h结尾的头文件中,在需要调用这个函数的 .c 源代码文件中 #include这个头文件,编译器在编译的时候就知道函数的原型了
新建——源代码——max.h max.h
double max(double a,double b);max.c
#include "max.h" double max(double a,double b) { return a > b ? a : b; }main.c
#include <stdio.h> #include "max.h" int main(void) { double a = 5; double b = 6; PRintf("max is %f\n", max(5, 6)); // max is 6.000000 return 0; }5.#include
#include是一个编译预处理命令,和宏一样,在编译之前就处理了 编译时,把头文件的全部文本内容 原封不动地 插入到 include所在的地方5.1 “” 还是 <>
#include 有两种形式来指出要插入的文件 ”“编译时,编译器首先在当前目录(.c文件所在的目录)寻找这个文件,如果没有 就到指定目录去找 <>编译时,编译器只在指定的目录去找 编译器知道标准库的头文件在哪里 环境变量 和 编译器命令行参数 也可以指令头文件的目录5.2 误区
#include 不是用来引入库的 现在的C语言编译器默认会引入所有的标准库 #include <stdio.h> 只是为了让编译器知道 printf函数的原型,保证你调用时给出的参数值是正确的类型 stdio.h 里只有printf()的原型,printf的代码在另外的某个 .lib(Windows)或.a(Unix)中6 头文件
一般的做法是 任何 .c 都有对应的同名的.h,把所有对外公开的函数原型 和 全局变量的生命 都放进去 在使用 和 定义 这个函数的地方都应该 #include 这个头文件7.声明
7.1 声明与定义
int i; // 变量的定义 extern int i; // 变量的声明 声明是不产生代码的 函数原型 变量原型 结构声明 宏声明 枚举声明 类型声明 inline函数 定义是产生代码的7.2 声明的使用
只有声明可以放在头文件中(是规则不是法律) 否则会造成一个项目中多个编译单元里有重名的实体 某些编译器允许几个编译单元中存在同名的函数,或者用weak修饰符来强调这种存在7.3 重复声明
同一个编译单元里,同名的结构不能被重复声明 如果头文件里有 结构的声明,很难保证 这个头文件 不会在一个编译单元里 被#include多次 需要“标准头文件结构” 运用条件编译和宏,保证这个头文件在一个编译单元中只会被#include一次 #pragma once 也能起到相同的作用,但是不是所有的编译器都支持错误示例:
struct Node{ int value; char* name; }; // [Error] redefinition of 'struct Node' 重新定义 struct Node struct Node{ int value; char* name; }; int main(void) { return 0; }标准写法: max.h
#ifndef _MAX_H_ #define _MAX_H_ double max(double a,double b); extern int gAll; struct Node{ int value; char* name; }; #endifmax.c
#include <stdio.h> #include "max.h" int gAll = 12; int main(void) { double a = 5; double b = 6; printf("max is %f\n", max(5, 6)); // max is 6.000000 return 0; }max.c
#include "max.h" double max(double a,double b) { return a > b ? a : b; }