美文网首页我爱编程
.h头文件与.c源文件的关系

.h头文件与.c源文件的关系

作者: xiaofeixiazyh | 来源:发表于2018-05-25 22:28 被阅读0次

    1 理解编译器

    插曲: 编译型和解释型语言的区别(举一个形象的例子):编译型语言(c)是做完一锅的菜,然后才能开始吃饭;而解释型语言(python)就像吃火锅,边做饭边吃饭。

    编译的过程: 预处理阶段——词法和语法分析阶段——编译阶段 ——连接阶段

    源程序->词法分析器->语法分析器->语义分析器->中间代码生成器->代码优化器->代码生成器->目标程序
    .
    eg:

    //  main.c
    #include <stdio.h>   // 系统自带的头文件
    #include "mytest.h"
    
    int mian(int argc, char **argv)
    {
    test = 25;
    printf("test............%d/n",test);
    }
    
    //main.h
    int test;
    

    我们来借助这个例子详细的讲一下编译的过程:
    1.预处理阶段和语法分析阶段:编译器以C文件作为一个单元,首先读这个包含mian函数这个文件,发现第一局和第二句是包含头文件,就会在工程中的所有文件中寻找这两个头文件,找到之后,就会进入相应的头文件中。在头文件中干的事就是处理宏定义、变量、函数声明、嵌套的头文件等,检测依赖关系,进行宏替换,看是否存在重复定义与声明的情况发生,最后将mian.c中包含的头文件的所有信息都扫描进来,形成一个中间得mian.c文件。

    2.编译阶段:上一步中将test变量扫描进入一个中间的C文件,这个test变量就变成了这个文件的一个全局变量,此时就将这个中间C文件中的所有变量、函数分配空间,将各个函数编译成二进制代码,按照特定文件格式生成目标文件。

    3.连接阶段:将上一步成生的各个目标文件连接生成最终的可执行文件。


    2 .*c and *.h

    首先,我们要理解#include的用途,其等价于将头文件中的内容复制粘贴到*.c中
    然后我们来看一下他们分别用于干什么:
    *.h 文件: 宏定义、函数、变量的声明
    *.c文件: 变量、函数的定义
    容易出现的错误:
    1. 在头文件中实现一个函数体,那么如果在多个C文件中引用它,而且又同时编译多个C文件,在每个引用此头文件的C文件所生成的目标文件中,都有一份这个函数的代码,就会发现多个相同的函数,就会报错。
    2.如果在头文件中定义全局变量,并且将此全局变量赋初值,那么在多个引用此头文件的C文件中同样存在相同变量名的拷贝。
    3.如果在C文件中声明宏,结构体,函数等,那么我要在另一个C文件中引用相同的宏,结构体,就必须再做一次重复的工作,如果我改了一个C文件中的一个声明,那么又忘了改其它C文件中的声明,这不就出了大问题了,程序的逻辑就变成了你不可想象的了,如果把这些公共的东东放在一个头文件中,想用它的C文件就只需要引用一下就OK了!!!这样岂不方便,要改某个声明的时候,只需要动一下头文件就行了。
    4.在头文件中声明结构体,函数等,当你需要将你的代码封装成一个库,让别人来用你的代码,你又不想公布源码,那么人家如何利用你的库呢?也就是如何利用你的库中的各个函数呢??一种方法是公布源码,别人想怎么用就怎么用,另一种是提供头文件,别人从头文件中看你的函数原型,这样人家才知道如何调用你写的函数.


    最后让我们来总结一下头文件存在的意义:

    • 使得程序简明,清晰.
    • 避免了重复编写相同的声明代码.
    • *.c and *.h文件没有必然的联系.

    相关文章

      网友评论

        本文标题:.h头文件与.c源文件的关系

        本文链接:https://www.haomeiwen.com/subject/ietpjftx.html