6.3 大程序结构

来源:互联网 发布:淘宝网充值中心 编辑:程序博客网 时间:2024/06/03 23:42

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;};#endif

max.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;}
0 0