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文件作用是被其它文件包含,是不参与编译的。

  • 相关阅读:
    Linux ->> VirtualBox Linux虚拟机与Windows主机共享目录
    Linux ->> CentOS 7 执行service network restart 报错
    借助企业微信实现“调接口”给个人微信发消息
    idea提交代码到github教程
    Content type ‘multipart/form-data;boundary=--------------------------9107
    org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;bounda
    org.hibernate.LazyInitializationException: could not initialize proxy 解决方案(JPA)
    GitLab代码回滚到特定版本
    js 导入excel文件
    GoLand 2021.1.3安装之后需要激活得步骤
  • 原文地址:https://www.cnblogs.com/CoderHong/p/10090667.html
Copyright © 2011-2022 走看看