Linux编译器——gcc/g++(预处理、编译、汇编、链接)

目录
0.程序实现的两大环境
1.gcc如何完成
预处理
编译
汇编
链接
2.动态库与静态库
对比二者生成的文件大小
3. gcc常用选项
0.程序实现的两大环境
任何一个C程序的实现都要经过翻译环境与执行环境。
在翻译环境中又分为4个部分,预编译、编译、汇编与链接。在各个阶段主要完成的任务有:
1.预编译(预处理):头文件的包含、注释的删除、#define符号的替换;
2.编译:将C语言代码转化为汇编代码;
3.汇编:把汇编指令转化为二进制指令;
4.链接:合并符号表和段表,生成可执行程序。

更多详细关于程序实现的两大环境的知识请参考:程序实现的两大环境 。
1.gcc如何完成
通过gcc指令的不同选项可查看各阶段所形成的文件;
格式:gcc [选项] [目标文件名] -o [生成文件名]。
首先在Test.c文件中写好C代码:
//Test.c
#include<stdio.h>#define N 100//这是一段注释.....int main()
{int n = 0;printf("Hello World\n");printf("%d\n", n + N);return 0;
}
预处理
查看 Test.c 预处理后的结果,-E选项的作用是让 gcc 在预处理结束后停止编译过程;-o 的作用是将预处理后的内容保存到 test.i 文件中。
gcc -E Test.c -o test.i

如图所示,预处理阶段进行了头文件包含、注释的删除、#define的替换。
编译
接下来将刚刚生成的 test.i 进行编译,并在编译之后停下来,将结果写入 test.s 中。gcc所用选项为 -S。
gcc -S test.i -o test.s

我们虽然可能没学习过汇编语言,但依旧隐约认识到这些就是汇编代码;可见编译阶段就是将C代码翻译为汇编指令。
汇编
gcc所用选项为 -c;-o 将结果写入到 test.o 中。
gcc -c test.s -o test.o

正如我们所见,汇编完成之后都这这样的乱码。其实汇编之后,生成的文件为二进制文件,是用来给计算机看的,咱们已经看不懂了。
链接
编译完成之后就进入了链接阶段,链接完成之后就会生成可执程序 Test了。
gcc test.o -o Test

但是关于链接,我们需要知道它在链接什么。
我们是否好奇过为什么我们明明没有定义过函数 printf 、return .....等等的函数,但却可以使用它的功能?
其实,系统把这些函数的实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函 数 printf 了,而这也就是链接的作用。
2.动态库与静态库
函数库一般分为动、静态库两种。二者的区别可以理解为私有与公共的区别。就好比我们需要读一本《C和指针》,有两种方法可以选。一种是自己买一本,只有自己可以用,用起来还挺方便,缺点就是得花钱;第二种是去图书馆借书,图书馆的资源被所有人共享。
gcc 进行函数库的链接时可选择静态链接或者动态链接。
静态链接就类似于自己买书看,只给自己看同时还费钱(浪费内存),静态链接时会将库文件的代码全部加入到可执行文件中,因此生成的文件比较大。
动态链接类似于去图书馆借书。函数库就放在某个固定的地方,哪个程序想去使用就去自己去加载它。
Linux下gcc默认使用动态链接。
对比二者生成的文件大小
//采用静态链接
gcc -static Test.c -o Test_static
//默认采用动态链接
gcc Test.c -o Test
若在静态链接时出错,可能是因为你的 Linux 没有安装C语言的静态库,须手动安装。
//安装C语言静态库
yum install -y glibc-static
两种连接方式生成的文件大小几乎相差百倍。
3. gcc常用选项
以下是gcc编译器常用选项汇总
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面;
-S 编译到汇编语言不进行汇编和链接;
-c 编译到目标代码;
-o 文件输出到 文件;
-static 此选项对生成的文件采用静态链接;
-g 生成调试信息。GNU 调试器可利用该信息;
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.;
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高;
-w 不生成任何警告信息;
-Wall 生成所有警告信息。
相关文章:
Linux编译器——gcc/g++(预处理、编译、汇编、链接)
目录 0.程序实现的两大环境 1.gcc如何完成 预处理 编译 汇编 链接 2.动态库与静态库 对比二者生成的文件大小 3. gcc常用选项 0.程序实现的两大环境 任何一个C程序的实现都要经过翻译环境与执行环境。 在翻译环境中又分为4个部分,预编译、编译、汇编与链…...
Java 操作图片进行缩放旋转翻转加水印
1 纯原生手写图片操作工具类 import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.image.BufferedImage; public class RotateImageUtil {public static BufferedImage rotateImage(BufferedImage bu…...
不能去演唱会现场就多听听耳机里的他们,教你用python来实现一个音乐播放器
前言 最近可以说大麦网很知名了,哈哈还有好多想要用Python来搞抢票脚本的 怎么说呢也不是不行,但是咱今天可不是来搞这个的,我可不抢票,抢了都去不了,上班搞钱啊铁铁们 咱就是说去不了现场,就多听听手机…...
CLion Debug 调试 Makefile 构建的 C 语言程序断点不起作用
最近在研究 jattach,打算在本地调试项目,发现 CLion 可以正常编译运行代码,却无法断点 Debug。由于笔者对 C/C 项目不熟悉,在此记录研究过程中遇到的一些基本问题与解决方法。 文章目录解决方式尝试过的手段【未解决】找 Native D…...
·神经网络
目录11神经网络demo112神经网络demo213神经网络demo320tensorflow2.0 安装教程,所有安装工具(神经网络)21神经网络-线性回归- demo122神经网络-线性回归- demo228神经网络-多层感知- demo1目录11神经网络demo1 package com.example.xxx; import java.ut…...
【Java 多线程学习】
多线程学习多线程1. 并行与并发2.进程和线程3. *****多线程的实现方式3.1 继承Thread类的方式进行实现3.2 实现Runnable接口方式进行实现3.3 利用Callable和Future接口方式实现3.4 设置获取线程名字4.获得线程对象5.线程休眠6.线程调度[线程的优先级]7.后台线程/守护线程多线程…...
【计算机考研408】快速排序的趟数问题 + PAT 甲级 7-2 The Second Run of Quicksort
前言 该题还未加入PAT甲级题库中,可以通过购买2022年秋季甲级考试进行答题,纯考研题改编 快速排序 常考的知识点 快速排序是基于分治法快速排序是所有内部排序算法中平均性能最优的排序算法快速排序是一种不稳定的排序算法快速排序算法中,…...
CSS-Grid(网格)布局
前言 之前HTML 页面的布局基本上都是通过 Flexbox 来实现的,能轻松的解决复杂的 Web 布局。 现在又出现了一个构建 HTML 最佳布局体系的新竞争者。就是强大的CSS Grid 布局。 grid和flex区别是什么?适用什么场景? Flexbox 是一维布局系统&am…...
软件测试4
一 form表单标签 1.form表单标签里面就是所有用户填写的表单数据; action“xxx.py”把表单数据提交给哪一个后台程序去处理 method“post” 传递数据时候的方式方法,post代表隐式提交数据、get明文传送数据 2.input标签的type类型 type“text” 普通的输…...
996的压力下,程序员还有时间做副业吗?
996怎么搞副业? 这个问题其实蛮奇怪的:996的压力下,怎么会还想着搞副业呢? 996还想搞副业的原因有哪些? 大家对于996应该都不陌生,总结就是一个字:忙。 996的工作性质就是加班,就…...
每日学术速递3.1
CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Directed Diffusion: Direct Control of Object Placement through Attention Guidance 标题:定向扩散:通过注意力引导直接控制物体放置 作者:…...
金融行业数据模型
一、Teradata FS-LDM Teradata 公司基于金融业务发布的FS-LDM(Financial Servies Logical Data Model) 十大主题:当事人、产品、协议、事件、资产、财务、机构、地域、营销、渠道。 1、当事人(Party) 银行所服务的任…...
【面试题】2023前端vue面试题及答案
Vue3.0 为什么要用 proxy?在 Vue2 中, 0bject.defineProperty 会改变原始数据,而 Proxy 是创建对象的虚拟表示,并提供 set 、get 和 deleteProperty 等处理器,这些处理器可在访问或修改原始对象上的属性时进行拦截&…...
(哈希查找)leetcode128. 最长连续序列
文章目录一、题目1、题目描述2、基础框架3、原题链接二、解题报告1、思路分析2、时间复杂度3、代码详解三、本题小知识一、题目 1、题目描述 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。…...
js中splice方法和slice方法
splice方法用来操作数组splice(startIndex,deleteNum,item1,....,)此操作会改变原数组。删除数组中元素参数解释:startIndex为起始index索引。deleteNum为从startIndex索引位置开始需要删除的个数。分三种情况:没有传第三个参数的情况下,dele…...
c++ argparse
需求 c程序传参数,像python中argparse一样方便。 方法1 用gflags 参考https://heroacool.blog.csdn.net/?typeblog git clone https://github.com/gflags/gflags cd gflags # 进入项目文件夹 cmake . # 使用 cmake 编译生成 Makefile 文件 make -j 24 # make 编…...
内大892复试真题16年
内大892复试真题16年 1. 输出三个数中较大数2. 求两个数最大公约数与最小公倍数3. 统计字符串中得字符个数4. 输出菱形5. 迭代法求平方根6. 处理字符串(逆序、进制转换)7. 寻找中位数8. 输入十进制输出n进制1. 输出三个数中较大数 问题 代码 #include <iostream>usin…...
面试题 05.02. 二进制数转字符串
二进制数转字符串。给定一个介于0和1之间的实数(如0.72),类型为double,打印它的二进制表达式。如果该数字无法精确地用32位以内的二进制表示,则打印“ERROR”。 示例1: 输入:0.625输出:"0…...
MySQL数据更新操作
文章目录前言添加数据插入数据删除数据修改数据前言 提示:这里可以添加本文要记录的大概内容: 数据更新有两种办法: 1:使用数据可视化工具操作 2:SQL语句 添加数据 前面的添加数据命令一次只能插入一条记录。如果想…...
C# 封装
修正bug之前总是要考虑是什么导致了这个bug,并花些时间了解发生了什么。增加打印输出行的语句可能是一个很有效的调试工具。增加语句来打印诊断信息时,要使用Debug.WriteLine。构造器是CLR第一次创建一个新对象实例时调用的方法。字符串插值会让字符串拼…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
