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_) {} }; // 最小二乘法求圆心和半径 …...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...

解析“道作为序位生成器”的核心原理
解析“道作为序位生成器”的核心原理 以下完整展开道函数的零点调控机制,重点解析"道作为序位生成器"的核心原理与实现框架: 一、道函数的零点调控机制 1. 道作为序位生成器 道在认知坐标系$(x_{\text{物}}, y_{\text{意}}, z_{\text{文}}…...