概述

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

窥探C语言程序的编译、链接与.h文件的更多相关文章

  1. C语言程序经过编译链接后形成二进制映像文件的组成

    C语言程序经过编译链接后形成二进制映像文件由栈,堆,数据段,代码段组成,其中数据段又分为:只读数据段,已经初始化读写数据段,未初始化数据段(BSS段).如下图所示: 1.栈区(stack):由编译器自 ...

  2. 13_传智播客iOS视频教程_OC程序的编译链接

    C程序的编译.链接.执行怎么来的?在.C文件里面写上符合C语言部分的源代码.OC也是一样的.记住:OC程序的后缀名是.m. 为什么要链接?第一个.o的目标文件里面它启动不了.因为它没有启动代码我们要加 ...

  3. iOS_02_第一个C语言程序(理解编译、连接、运行)

    一.开发工具的选择 1. 可以用来写代码的工具:记事本.ULtraEdit.Vim.Xcode等. 2. 选择XCode的原因:苹果公司官方提供的开发利器.简化开发的工程.有高亮显示功能. 3. 使用 ...

  4. 读书笔记-详解C程序开发中 .c和.h文件的区别

    一个简单的问题:.c和.h文件的区别 学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼: 子程序不要定 ...

  5. Ubuntu下编译C语言程序(同时给编译生成的文件命名)

    1.创建c文件 test.c touch test.c 2.编写test.c vim test.c #include "stdio.h" int main(){ printf(&q ...

  6. 通过终端编译链接运行C文件

    1.创建c文件 touch demo.c 2.编辑c代码 3.编译(预编译.检查语法.编译).链接 3.1.指令:cc  -c  demo.c 正常情况下,会生成一个demo.o的二进制文件(即:目标 ...

  7. 计算机二级-C语言-程序填空题-190117记录-对文件的处理,复制两个文件,往新文件中写入数据。

    //给定程序的功能是,调用函数fun将指定源文件中的内容赋值到指定目标文件中,复制成功时函数返回1,失败时返回0,把复制的内容输出到终端屏幕.主函数中源文件名放在变量sfname中,目标文件名放在变量 ...

  8. Linux C程序的编译过程

    Linux C程序的编译过程 学习一门语言程序,本人觉得还是得学习它的编译规则,现在,通过小例子小结下自己对C编译的认识. /*test.c     了解C程序的编译*/ #include <s ...

  9. [转]C++编译链接过程详解

    C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作 ...

随机推荐

  1. QueryList 来做采集是什么样子

    采集百度搜索结果列表的标题和链接. $data = QueryList::get('https://www.baidu.com/s?wd=QueryList') // 设置采集规则 ->rule ...

  2. Python 爬取12306火车票

    获取火车站 stations.py #import certifi #import urllib3 import re import requests from pprint import pprin ...

  3. opencv-图像形态学之开运算、闭运算、形态学梯度、顶帽、黑帽合辑

    转自:https://blog.csdn.net/poem_qianmo/article/details/24599073 1.1 开运算(Opening Operation) 开运算(Opening ...

  4. Centos 6 & Centos 7安装rabbitmq3.6.15(单节点)

    系统准备 安装 erlang 语言环境 安装rabbitmq 配置网页插件 配置访问账号密码和权限 系统准备 centos6.5 与 centos7 都可以 ###安装依赖文件 yum -y inst ...

  5. Codeforces 1174C Ehab and a Special Coloring Problem

    题目链接:http://codeforces.com/problemset/problem/1174/C 题意:给你一个n,要你填充 下标由2 ~ n 的数组ai,要求下标互质的俩个数不能相等,并且数 ...

  6. [kuangbin带你飞]专题一 简单搜索 - L - Oil Deposits

    #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #i ...

  7. Netty环境安装配置

    本章中介绍的Netty开发环境的安装及配置; 这个一系列教程示例的Netty最低要求只有两个:最新版本的Netty 4.x和JDK 1.6及更高版本. 最新版本的Netty在项目下载页面中可找到:ht ...

  8. linux下链接时缺少动态链接库

    1, 用ln将需要的so文件链接到/usr/lib或者/lib这两个默认的目录下边 ln -s /where/you/install/lib/*.so /usr/libsudo ldconfig 2, ...

  9. delphi 流程单打印

    1.添加声明 f_count1: double; 2.得到拆分页数量 // Modified by 884 2018-04-20 14:50:18 AM0057 with aqTpCount do b ...

  10. CSIC_716_20191111【函数对象、名称空间、作用域、global 和nonlocal】

    函数名是可以被引用,传递的是函数的内存地址.函数名赋值给变量后,只需要在变量后加上括号即可调用函数. 名称空间 内置名称空间:在python解释器中提前定义完的名字 全局名称空间:if.while.f ...