窥探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文件作用是被其它文件包含,是不参与编译的。
窥探C语言程序的编译、链接与.h文件的更多相关文章
- C语言程序经过编译链接后形成二进制映像文件的组成
C语言程序经过编译链接后形成二进制映像文件由栈,堆,数据段,代码段组成,其中数据段又分为:只读数据段,已经初始化读写数据段,未初始化数据段(BSS段).如下图所示: 1.栈区(stack):由编译器自 ...
- 13_传智播客iOS视频教程_OC程序的编译链接
C程序的编译.链接.执行怎么来的?在.C文件里面写上符合C语言部分的源代码.OC也是一样的.记住:OC程序的后缀名是.m. 为什么要链接?第一个.o的目标文件里面它启动不了.因为它没有启动代码我们要加 ...
- iOS_02_第一个C语言程序(理解编译、连接、运行)
一.开发工具的选择 1. 可以用来写代码的工具:记事本.ULtraEdit.Vim.Xcode等. 2. 选择XCode的原因:苹果公司官方提供的开发利器.简化开发的工程.有高亮显示功能. 3. 使用 ...
- 读书笔记-详解C程序开发中 .c和.h文件的区别
一个简单的问题:.c和.h文件的区别 学了几个月的C语言,反而觉得越来越不懂了.同样是子程序,可以定义在.c文件中,也可以定义在.h文件中,那这两个文件到底在用法上有什么区别呢? 2楼: 子程序不要定 ...
- Ubuntu下编译C语言程序(同时给编译生成的文件命名)
1.创建c文件 test.c touch test.c 2.编写test.c vim test.c #include "stdio.h" int main(){ printf(&q ...
- 通过终端编译链接运行C文件
1.创建c文件 touch demo.c 2.编辑c代码 3.编译(预编译.检查语法.编译).链接 3.1.指令:cc -c demo.c 正常情况下,会生成一个demo.o的二进制文件(即:目标 ...
- 计算机二级-C语言-程序填空题-190117记录-对文件的处理,复制两个文件,往新文件中写入数据。
//给定程序的功能是,调用函数fun将指定源文件中的内容赋值到指定目标文件中,复制成功时函数返回1,失败时返回0,把复制的内容输出到终端屏幕.主函数中源文件名放在变量sfname中,目标文件名放在变量 ...
- Linux C程序的编译过程
Linux C程序的编译过程 学习一门语言程序,本人觉得还是得学习它的编译规则,现在,通过小例子小结下自己对C编译的认识. /*test.c 了解C程序的编译*/ #include <s ...
- [转]C++编译链接过程详解
C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作 ...
随机推荐
- thinkphp cookie支持
系统内置了一个cookie函数用于支持和简化Cookie的相关操作,该函数可以完成Cookie的设置.获取.删除操作. Cookie设置 cookie('name','value'); //设置coo ...
- C++——函数模板和类模板
声明: //template 关键字告诉C++编译器 我要开始泛型了.你不要随便报错 //数据类型T 参数化数据类型 template <typename T> void myswap(T ...
- NX二次开发-UFUN单对象选择对话框UF_UI_select_with_single_dialog
#include <uf.h> #include <uf_ui.h> ], void* user_data, UF_UI_selection_p_t select) { if ...
- NX二次开发-设置尺寸的附加尺寸UF_DRF_set_appended_text
#include <uf.h> #include <uf_drf.h> #include <uf_obj.h> #include <uf_part.h> ...
- var 更明确地表示一个变量被设置为零值
创建一个变量并被初始化其为零值,习惯使用关键字var.这种做法是为了更明确地表示一个变量被设置为零值. 如果变量被初始化为某个非零值,就配合结构字面量和短变量操作符来创建变量. 零值 数值类型:0 字 ...
- ionic:ionic 教程
ylbtech-ionic:ionic 教程 1.返回顶部 1. ionic 教程 ionic 是一个强大的 HTML5 应用程序开发框架(HTML5 Hybrid Mobile App Framew ...
- LeetCode 596. Classes More Than 5 Students (超过5名学生的课)
题目标签: 题目给了我们 courses 表格,让我们找到 一个有至少5名学生的班级. 利用group by 把班级分类,在用Having count 来判断是否有5名,注意这里还需要用 distin ...
- c++-字符串和时间操作
C++ 字符串 C++ 提供了以下两种类型的字符串表示形式: C 风格字符串 C++ 引入的 string 类类型 C 风格字符串 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持.字符 ...
- CodeForces 1152F2 Neko Rules the Catniverse (Large Version)
题目链接:http://codeforces.com/problemset/problem/1152/F2 题目大意 见http://codeforces.com/problemset/problem ...
- 《DSP using MATLAB》Problem 8.45
代码: %% ------------------------------------------------------------------------ %% Output Info about ...