ObjectiveC学习准备__C语言2

本章重点:C语言头文件。

用命令行编译C文件我们已经知道了

简单谈一下他的编译过程..

首先我们创建了test.c的C文件 也就是源文件, 接着预编译,再由编译器编译为汇编代码,

汇编器把汇编代码编译为目标文件(.o),最后由连接器把所有目标文件与库文件连接起来生成可执行文件

源文件->预编译文件->汇编代码文件->目标文件->链接后生成可执行文件;

下面学习头文件与实现文件的意义

我们都知道C语言编程第一行是什么呢

1 #include <stdio.h>
2 int main(){
3  printf("Hellow Word");       
4 }

是的,是#include导入头文件  大家可以试试把第一行去掉

gcc 编译是不是error了?错误提示告诉你printf函数不存在  是的,这个打印输出只是<stdio.h>库文件里的一个方法,所以必须导入库文件。

如果我们自己编译的程序有几千行甚至更多..都写在一个test.c那么维护起来是不是很麻烦?代码重用性也很低..

对于这种问题头文件和实现文件就能很好地解决了

头文件是以.h结尾的文件 它的作用相当于其他语言的说明文档..头文件内只是声明属性,变量或方法并不去实现

那么如何实现这些方法呢?都写在实现文件.c里面  当然 两个文件的文件名是相同的  只是后缀不同

我们来做个例子..

创建头文件testA.h代码只有一行  声明一个sum方法; 

1 int sum(int,int); 

创建实现文件testA.c实现这个方法;

1 int sum(int i,int j)
2 {
3     return i+j;
4 }

创建测试文件test.c

1 #include <stdio.h>
2 #include "testA.h"
3 int main(){
4      int m = 5;
5      int n = 6;
6      int result = sum(m,n);
7     printf("%d\n",result);
8 }

编译运行 gcc -o test test.c testA.c

头文件是不需要编译的  但是实现文件需要跟测试文件一起进行连接  也可以先把实现文件编译成目标文件

gcc -c testA.c//得到目标文件testA.o

gcc -o test test.c testA.o

运行test.exe可以看到result输出了sum方法的返回值11;

可能有人会问 有实现文件实现方法就可以了 为什么要头文件呢   直接导入实现文件testA.c不可以吗?

当然不是不可以,直接#include "testA.c"导入实现文件不用头文件也是可以的;但头文件的意义何在呢?

这里就要讲到一个依赖倒转的理念了..依赖倒转是指:高层如果依赖于底层的话底层改变,高层也不得不改变,

那么代码维护和重用重用性就大大降低了,所以高层都应该依赖于抽象而不是底层这是依赖倒转原则。

只是这样说的话很多人可能不理解..我们来做个例子..

假设有两个实现文件testA.c,testB.c,各自对应头文件testA.h,testB.h

且testA.h依赖于testB.h

testA.c

int sum(int i,int j)
{
    return i+j;
}
int MULT (int i,int j)
{
    return MULTB(i,j);
}    

testA.h

#include "testB.h"
int sum(int,int);
int MULT (int,int);

testB.c

1 int MULTB(int i,int j)
2 {
3     return i*j;
4 }    

testB.h

int MULTB(int,int);

test.c

1 #include <stdio.h>
2 #include "testA.c"
3 int main(){
4      int m = 5;
5      int n = 6;
6      int result = MULT(m,n);
7      printf("%d\n",result);
8 }

可以看到testA.c的MULT()方法是依赖于testB.c的MULTB()方法实现的;

我们先来把testA.c,testB.c都编译为目标文件

gcc -c testA.c testB.c//得到testA.o,testB.o两个目标文件

再把目标文件与测试文件链接

gcc test.c testA.o testB.o//生成可执行文件

可以看到testA.c的头文件依赖于testB.c的头文件实现了MULT()方法

如果对testB.c的方法进行修改呢

testB.c

1 int MULTB(int i,int j)
2 {
3     return i+j;
4 }    

我们把乘法改成了除法  重新把testB.c编译成目标文件:gcc -c testB.c

再次链接生成可执行文件:gcc test.c testA.o testB.o

可以看到testA.o并没有重新编译  但testA.c的MULT()方法又是依赖于testB.c 为什么testA.c不用重新编译呢?

因为依赖所写是在头文件  程序通过头文件找到.o文件..头文件相当于声明了一个抽象方法..具体实现要看实现类怎么写

也就是说testA.c的MULT()方法是依赖于testB.h内的一个抽象方法,所以即使testB.c改变了,testA.c依然能使用而不用重新编译。

下面大家做一个测试

有A.c,B.c两个实现文件(内容随意)分别对应A.h,B.h两个头文件..

文件A.h依赖于文件B.h,文件B.h又依赖于文件A.h

test.c测试#include导入A.h 编译运行

原文地址:https://www.cnblogs.com/pengser/p/4913954.html