解密C语言编译背后的过程
我们大部分程序员可能都是从C语言学起的,写过几万行、几十万行、甚至上百万行的代码,但是大家是否都清楚C语言编译的完整过程呢,如果不清楚的话,我今天就带着大家一起来做个解密吧。
C语言相对于汇编语言是一种高级语言,要想在系统上运行,需要通过编译器把它转换成机器能够读懂的可执行的代码。
以Linux系统上的gcc为例,通常我们编译一个源文件都是用下面的命令:
$gcc hello.c –o hello

编译成功后,目录里会生成hello这个程序,直接运行它可以看到结果。
$./hello
Hello World!
但hello这个程序是怎么生成的呢,其实中间还是有好几步的。用下面这个命令重新编译一下,你可以看到所有的中间文件。
$gcc -save-temps hello.c –o hello
$ls
hello hello.c hello.i hello.o hello.s
C编译器的编译过程主要分成四步:
(1) 预处理
(2) 编译
(3) 汇编
(4) 连接

1) 预处理 Pre-prosssing
预处理生成了hello.i 的中间文件,主要完成了下面几步:
去掉所有的注释
展开所有的宏定义(也就是做字符替换)
插入#include文件的内容
处理所有的条件编译
hello.i 文件内容如下(文件较大,只展示了最下面的一块):

可以发现源代码中所有的注释被删除了,并且插入了stdio.h头文件的内容。
2)编译 Compiling
编译将 hello.i 文件编译生成一个中间文件 hello.s,打开可以看到里边都是汇编语言,所以编译的作用就是把源代码转换成汇编语言。

3)汇编 Assembly
汇编器将 hello.s 汇编成 hello.o 文件。hello.o是二进制文件,里边都是机器可以执行的代码。

4)连接 Linking
连接顾名思义起到了一个连接作用,虽然 hello.o 已经是二进制文件了,但是里边用到的比如 printf 函数需要调用别的库。连接器将我们的二进制文件和其他库做了一个绑定。可以看到连接后生成的 hello 文件要比 hello.o 大的多。

到这里 C的完整编译流程就结束了,本文的示例用的是Linux操作系统,编译器用的是 gcc,但在其他操作系统,比如 Unix、Windows,或者用其他编译器,原理都是一样的,感兴趣的同学可以去学习一下编译原理,会对编译有更深入的理解。

解密C语言编译背后的过程的更多相关文章
- C语言编译和链接过程
1.程序的编译 一般而言,大多数编译系统都提供编译驱动程序(complier driver),根据用户需求调用语言预处理器,编译器,汇编器和链接器.例如有如下历程://main.c void swa ...
- C语言编译过程简介
刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道为什么在windows平台下代码经过鼠标那样点击几下,程序的结果就会在那个黑色的屏幕上.现在找了个机会将C语言的编译原理做一下小小的总结,这样也能 ...
- C语言编译过程(转)
内容摘要 : C语言编译的整个过程是非常复杂的,里面涉及到的编译器知识.硬件知识.工具链知识都是非常多的,深入了解整个编译过程对工程师理解应用程序的编写是有很大帮助的,希望大家可以多了解一些,在遇到问 ...
- C语言编译过程及数据类型
写在前面 C语言可以称得上是高级语言中的低级语言,接下来一段时间,我会写一下文章关于c语言,把它的神秘面纱一 一揭开.下面主要是c语言的C语言编译过程及数据类型 源文件编译过程 为了使计算机能执行高级 ...
- C语言编译过程以及gcc编译参数
1.1 C语言编译过程,gcc参数简介 1.1.1 C语言编译过程 一.gcc - o a a.c -o:指定文件输出名字 二.C语言编译的过程: 1.1.1 ...
- C语言基础(21)-C语言编译过程及GCC参数简介
任何C语言的编译过程可分为以下三部分: 一.预编译 在C语言中,以#开头的语句又叫预编译指令.预编译主要做以下两件事情: 1.将#include包含的头文件做简单的文本替换: 2.将代码中的注释删除. ...
- 转 C语言编译过程简介
C语言编译过程简介 C语言编译过程简介 刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道为什么在windows平台下代码经过鼠标那样点击几下,程序的结果就会在那个黑色的屏幕上.现在找了个机会将C ...
- GCC 使用-C语言编译过程
任何一种高级语言,要想在机器上执行,必须翻译为机器能读懂的机器语言.编译器就相当于翻译官,将高级语言翻译为机器语言. GCC 最初只用了编译 C 语言程序,全称是 GNU C Compiler.后来扩 ...
- Go 语言编译过程
走进Golang之编译器原理_大愚Talk-CSDN博客 https://blog.csdn.net/hel12he/article/details/103061921 go编译器 - 知乎 http ...
随机推荐
- jquery 延迟执行方法
setTimeout方法使用时需注意: //以下两种方式都行: setTimeout(function () { test(); }, ); //或者 setTimeout(); function t ...
- k3s-初体验
k3s安装步骤 1.准备工作 关闭swap交换分区 swapoff -a 关闭防火墙 systemctl stop firewalld.service 2.下载启动k3s包 https://githu ...
- Python爬虫某招聘网站的岗位信息
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:阿尔法游戏 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
- S7通信协议之你不知道的事儿
在电气学习的路上,西门子PLC应该是我的启蒙PLC,从早期的S7-300/400 PLC搭建Profibus-DP网络开始接触,到后来的S7-200Smart PLC,再到现在的S7-1200/150 ...
- C# 基础知识系列- 12 任务和多线程
0. 前言 照例一份前言,在介绍任务和多线程之前,先介绍一下异步和同步的概念.我们之间介绍的知识点都是在同步执行,所谓的同步就是一行代码一行代码的执行,就像是我们日常乘坐地铁通过安检通道一样,想象我们 ...
- 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...
- 小白初学Java的一点点收获
作为刚刚学习Java没有几天的小白,我想把我在学习过程中,所学习到的知识和注意事项和大家一起分享分享.在这个过程中,希望大家可以有所收获,有什么不对的地方,希望大家指出并且私信我. 首先说说第一次记事 ...
- Java中的方法是什么以及方法的书写格式
方法:完成特定功能的代码块注意:在很多语言里面有函数的定义,而在Java中函数被称为方法.方法格式:修饰符 返回值类型+ 方法名 (参数类型 参数名1,参数类型 参数名2...){方法体语句;retu ...
- 理解java容器底层原理--手动实现HashMap
HashMap结构 HashMap的底层是数组+链表,百度百科找了张图: 先写个链表节点的类 package com.xzlf.collection2; public class Node { int ...
- 一个老牌程序员推荐的JavaScript的书籍,看了真的不后悔!
很多人问我怎么学前端?我的回答是:读书吧!相对于在网上学习,在项目中学习和跟着有经验的同事学习,书中有着相对完整的知识体系,每读一本好书都会带来一次全面的提高.而如果深一脚浅一脚的学习,写出代码的质量 ...