zoukankan      html  css  js  c++  java
  • 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 编译运行

  • 相关阅读:
    Effective Java 第三版——72. 赞成使用标准异常
    Effective Java 第三版——71. 避免不必要地使用检查异常
    Effective Java 第三版——70. 对可恢复条件使用检查异常,对编程错误使用运行时异常
    Effective Java 第三版——69. 仅在发生异常的条件下使用异常
    Effective Java 第三版——68. 遵守普遍接受的命名约定
    Effective Java 第三版——67. 明智谨慎地进行优化
    Effective Java 第三版——66. 明智谨慎地使用本地方法
    Effective Java 第三版——65. 接口优于反射
    Effective Java 第三版——64. 通过对象的接口引用对象
    Effective Java 第三版——63. 注意字符串连接的性能
  • 原文地址:https://www.cnblogs.com/pengser/p/4913954.html
Copyright © 2011-2022 走看看