zoukankan      html  css  js  c++  java
  • 窥探C语言程序的编译、链接与.h文件

    概述

    C语言程序从源文件经过编译、链接生成可执行文件。那么编译与链接分别做了什么? 开发中为什么使用.h编写函数的声明?接下来使用案例说清楚为什么这样编写代码。

    C语言程序的编译和链接

    C语言程序从源文件到生成可执行程序需要经过编译器的预处理,汇编、编译、链接。这里简化为编译、链接两个阶段

    编译:对源文件语法做检查
    链接:会查找函数的具体实现并把项目中所有相关的.o目标文件、C语言函数库合并在一起生成可执行文件

    我来编写一个main.c

    对main.c进行编译,可以用clang或者gcc编译器都可以

    $gcc -c main.c
    $clang -c main.c
    

    一旦执行编译你会发现,编译通过了,编译器只是提示一个警告

    警告只是告诉main.c调用sum函数没有函数声明,那我们添加sum函数声明再次编译

    perfect!编译完美通过,生成目标文件main.o

    接着问题就来了,mian.c根本就没有sum函数定义,怎么就可以编译通过呢? 编译只是检查语法,main.c中调用sum函数并且有函数声明就没有语法问题,编译自然可以通过。

    接下来你想生成可执行程序还差一步链接的操作

    $gcc main.o -o main
    $clang main.o -o main
    

    报错是因为找不到main.c中的调用sum函数的定义,链接失败。 由此证明链接会查找该文件调用所有函数的定义

    这次就完美了,可以编译器、链接一起来

    $gcc main.c -o main
    $clang main.c -o main
    

    编译链接通过,输出执行结果21

    C语言多文件开发

    上面main.c调用了函数sum,在企业开发中是分文件开发,现在模拟一个场景。
    A负责编写main.c, B负责编写Math.c(数学运算的一些函数)提供给A调用。

    $ gcc -c main.c Math.c
    $ gcc main.o Math.o -o app
    

    执行程序app运行成功!

    虽然A与B这样配合可以完成项目开发,但是会发现A调用B中的函数,需要去B的Math.c中找函数定义,并将在main.c中手动添加该函数的声明。这样做法是不合理的,Math.c是由B写的,B对它最熟悉的,对于调用者不需要这么麻烦,因此.h文件的作用就诞生了!

    B除了编写Math.c,还要维护一个.h文件,将Math.c可以供外界调用的函数声明写在.h中。这样A在调用只需要在main.c中包含Math.h文件即可。即使以后B的Math.c中新增加了函数,A不需要修改代码,查看Math.h有这个函数声明直接调用就可以了。

    .h文件作用是被其它文件包含,是不参与编译的。

  • 相关阅读:
    Codeforces 1009F Dominant Indices
    C++之++运算符重载问题
    Codeforces 1010D Mars rover
    这是一个开始
    MoreEffectiveC++Item35(异常)(条款9-15)
    C++隐式类类型转化
    MoreEffectiveC++Item35(操作符)(条款5-8)
    MoreEffectiveC++Item35(基础议题)(条款1-4)
    php+mysql网站无限级栏目分类-递归获取树形结构函数
    JavaScript简易动画
  • 原文地址:https://www.cnblogs.com/CoderHong/p/10090667.html
Copyright © 2011-2022 走看看