C语言学习(十八)大程序

在编写比较复杂的程序时,为了使程序看起来更加有条理,我们需要采取一些措施。之前我们已经学习了函数,但是有的时候只使用函数还是会看起来很混乱,这里我们就学习一下怎么使用多个.c文件来编写大程序。

1. 多个.c文件
main()里面的代码太长,适合分为几个函数;
一个源代码文件太长适合分为几个文件;
两个独立的源代码文件不能编译形成可执行的程序;

例1:多个.c文件的项目
首先新建一个项目,在源文件中新建MAIN.c以及max.c两个源文件。
对MAIN.c,程序代码为:

#include<stdio.h>

int max(int a,int b);    //函数声明

int main(void)
{
	int a=5;
	int b=6;
	printf("%d\n",max(a,b));
	return 0;
}

对max.c,程序代码为:

int max(int a,int b)
{
	return a>b?a:b;
}

编译单元:一个.c文件是一个编译单元,编译器每次只编译一个编译单元,然后再链接到一起。

2. 头文件
把函数原型放到一个头文件中,在需要调用这个函数的源代码文件中#include这个头文件,就能让编译器在编译的时候知道函数的原型。

例2:头文件
添加一个头文件为max.h。在max.h中写入代码:

int max(int a,int b);

删去main函数中的函数声明,并在MAIN.c和max.c写入:

#include “max.h”

#include是一个编译预处理指令,和宏一样,在编译之前就处理了。它会把那个文件的全部文本内容原封不动地插入到它所在的地方。

① 使用 ” ” 还是 < >
#include有两种形式来指出要插入的文件。
“”要求编译器首先在当前目录(.c文件所在目录)寻找这个文件,如果没有,到编译器指定的目录去找。
<>让编译器自己知道自己的标准库的头文件在哪里。
环境变量和编译器命令行参数也可以指定寻找头文件的目录。
综上,如果是自己写的头文件,使用””;如果是系统指定的头文件,使用<>。

② 使用头文件需要注意:
在使用和定义这个函数的地方都应该#include这个头文件;
一般的做法就是任何的.c文件都有对应同名的.h,把所有对外公开的原型和全局变量的声明都放进去。

③ 不对外公开的函数:
在函数前面加上static就使得它成为只能在所在的编译单元中被使用的函数;
在全局变量前面加上static就使得它成为只能在所在的编译单元中被使用的全局变量。

3. 声明

① 变量的声明
在max.c中有一个全局变量g,我们要在main.c里面也要访问到这个全局变量g,需要在.h文件声明全局变量。

int I;是变量的定义
extern int I;是变量的声明

② 声明和定义
声明是不产生代码的东西,包括:函数原型、变量声明、结构声明、宏声明、枚举声明、类型声明、inline函数。定义是会产生代码的。

③ 头文件
只有声明可以放到头文件中,否则会造成一个项目中多个编译单元有重名的实体。某些编译器允许几个编译单元存在同名的函数,或者用weak修饰符来强调这种存在。

对于结构声明,我们在代码比较多的情况下可能会出现重复声明的情况,为了避免这种情况,我们可以把结构声明放到.h文件中去。

④ 标准头文件结构
如果我们加入了两个头文件,在min.h中我们#include了max.h,这样的话我们可能会重复声明结构体,这种情况在程序很复杂的时候是不容易避免的,因此我们需要引入标准头文件结构。
#ifndef MAX_H //如果没有定义,定义过的话就跳过
#define MAX_H//进行定义
……
#endif

例3:声明
min.h文件:

#include "max.h"
max.h文件:
#ifndef _MAX_H_
#define _MAX_H_

int max(int a,int b);

extern int g;

struct Node{      //结构声明
	int value;
	char* name;
};

#endif

max.c文件:

#include "max.h"

int g=12;

int max(int a,int b)
{
	return a>b?a:b;
}

MAIN.c文件:

#include<stdio.h>
#include "max.h"
#include "min.h"

int main(void)
{
	int a=5;
	int b=6;
	printf("%d\n",max(a,g));
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_33523925/article/details/87886316