【Linux】编译器gcc/g++及其库的详细介绍

前言:

        上文我们学到了,LInux中的的编辑器vim【Linux】vim编辑器-CSDN博客

        本文来学习LInux中的编译器:gcc/g++

        gcc是C语言编译器,g++是C++编译器,这两个的使用一模一样。这里我们主要使用gcc给大家介绍

 1.格式

gcc  被编译的源文件   选项   编译的目标文件

选项:-o,生成指定文件

若不指定文件则默认生成a.out,若自定则生成指定的可执行文件

hyc@hcss-ecs-4ce7:~$ ls
new  new.c#未指定
hyc@hcss-ecs-4ce7:~$ gcc new.c
hyc@hcss-ecs-4ce7:~$ ls
a.out  new  new.c
hyc@hcss-ecs-4ce7:~$ ./a.out
存在
存在
存在
存在
存在#指定
hyc@hcss-ecs-4ce7:~$ gcc new.c -o new.exe
hyc@hcss-ecs-4ce7:~$ ls
new  new.c  new.exe
hyc@hcss-ecs-4ce7:~$ ./new.exe
存在
存在
存在
存在
存在

2.编译的过程 

2.1预处理

预处理的功能包括:替换宏定义、头文件展开、条件编译、去注释等

预处理的指令是从#开始的代码行

.c文件经过预处理会形成.i文件

-E选项:使编译器处理完预处理就停下

hyc@hcss-ecs-4ce7:~$ ls
new  new.chyc@hcss-ecs-4ce7:~$ gcc -E new.c -o new.i
hyc@hcss-ecs-4ce7:~$ ls
new  new.c   new.i

2.2编译

编译主要功能:检查.i文件代码是否规范,是否有语法错误。检查无误后gcc将代码翻译为汇编语言,生成.s文件

-S选项:使编译器处理完编译就停下

hyc@hcss-ecs-4ce7:~$ ls -l
total 28
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.ihyc@hcss-ecs-4ce7:~$ gcc -S new.i -o new.s
hyc@hcss-ecs-4ce7:~$ ls -l
total 32
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s

补充:为什么要将代码翻译成汇编?

        在计算机刚刚诞生的时代,没有任何编程语言,科学家是通过计算机上的元器件开关来控制计算机的。后来科学家发明了”打孔编程“,通过纸袋传递二进制信息

        再后来又发明了汇编语言,但汇编语言无法直接传递二进制信息。于是对于汇编语言的编译器诞生了。通过编译器将汇编语言映射为二进制,来操控计算机

        再后来就出现了各种各样的编译性语言:例如C/C++,java,python等等等等。对于这些语言我们也需要将其翻译为二进制,计算机才能明白我们的意图。

        但是这里有两条路:C -> 二进制,C ->汇编?选着哪条?

        显然我们选着了第二条路,因为C语言到二进制这无疑就困难的。而C到汇编语言仍是文本上的翻译,相对简单。我们可以直接站在巨人的肩膀上不用做二进制的翻译。

补充:编译器的诞生

        汇编语言被发明了,想要汇编语言被翻译成二进制,那么需要一个编译器来编译汇编语言。那汇编语言的编译器是怎么来的?答案是:先通过二进制编写一个编译器,得到汇编语言的编译器后,再通过使用汇编语言写一个汇编编译器。最终得到一个汇编版的汇编编译器。

        同理C语言被发明了,想要有一个C语言的编译器,只能先使用汇编语言编写一个C语言编译器,在通过C语言编译器写一个C语言的编译器。最终得到一个C语言版的C语言编译器。

        这就是编译器的自举

2.3汇编

汇编主要功能:将.s文件转化为机器可识别的二进制文件(.o)

-c选项:使编译器处理完汇编就停下

hyc@hcss-ecs-4ce7:~$ ls
new  new.c  new.i  new.shyc@hcss-ecs-4ce7:~$ gcc -c new.s -o new.o
hyc@hcss-ecs-4ce7:~$ ls -l 
total 36
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc  1744 Jun  3 13:42 new.o
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s

2.4连接

将库方法与我们自己写的目标文件连接起来,形成可执行文件

hyc@hcss-ecs-4ce7:~$ gcc new.o -o new.exe
hyc@hcss-ecs-4ce7:~$ ls -l
total 52
drw-rwxr-x 2 hyc hyc  4096 May 26 15:41 new
-rw-rw-r-- 1 hyc hyc   219 May 29 21:58 new.c
-rwxrwxr-x 1 hyc hyc 15960 Jun  3 13:51 new.exe
-rw-rw-r-- 1 hyc hyc 18047 Jun  3 13:31 new.i
-rw-rw-r-- 1 hyc hyc  1744 Jun  3 13:42 new.o
-rw-rw-r-- 1 hyc hyc   895 Jun  3 13:38 new.s
hyc@hcss-ecs-4ce7:~$ ./new.exe
存在
存在
存在
存在
存在

补充:

记忆选项:ESc

记忆文件后缀:.iso

对于编译器来说一般都是先将所有的文件编译为 .o文件,再将全部 .o文件一起连接

3.理解条件编译

条件编译是在预处理阶段执行的,其具体操作是将不满足条件的代码直接抹去,只保留满足条件的

演示:

新建一个代码

保存并退出,我们让其进行预处理,然后再查看代码

hyc@hcss-ecs-4ce7:~$ gcc -E test.c -o test.i
hyc@hcss-ecs-4ce7:~$ vim test.i

我们可以看到代码就只剩第一个printf函数了。

同时编译器还支持在命令行中动态的定义宏

#使用-D选项,可以实现在命令行中动态的定义宏hyc@hcss-ecs-4ce7:~$ gcc test.c -o test
hyc@hcss-ecs-4ce7:~$ ./test
收费->专业版
hyc@hcss-ecs-4ce7:~$ gcc test.c -o test -DM=10
hyc@hcss-ecs-4ce7:~$ ./test
免费->社区版

预处理的本质就是编辑我们的代码。像我们用到的vs、xshell等等工具都有社区版和专业版的区别,但不论是那个版本其本质都是同一个项目,只是使用了条件编译将专业版进行阉割作为社区版供给普通人免费使用。

4.动态库静态库

什么的库?

        库是编程中的 “工具箱”,通过复用成熟代码,让开发者聚焦业务逻辑,大幅提升开发效率和代码质量。从基础的标准库到专业的第三方库,它们构成了现代软件开发的核心生态,是实现快速迭代和复杂功能的关键支撑。

补充:ldd指令

ldd指令可以让我们查看可执行程序依赖了那些库

这里我们可以看到这个可执行程序依赖了C语言的动态库。

库的命名方式

动态库 :

在代码加载到内存时,会进行动态连接:将程序中要使用的库实现函数,在库中找到相应位置,并对函数地址进行替换。这样在调用对应函数时,就会直接跳转到库中相应位置进行执行。执行完毕跳转回来继续向下执行

静态库:

静态库与动态库相反,在编译阶段就会将所需要部分的代码,直接拷贝到我们自己的代码中

补充:

1.Linux下动态库为:xxx.so    静态库为:xxx.a

   windows下动态库为:xxx.dll    静态库为:xxx.lib

2.静态库只在连接时有用,一旦形成可执行文件后, 就不再需要了

动静态库对比

1.动态库所形成的可执行文件,体积小

2.可执行文件对静态库依赖小,动态库依赖大不可缺失

3.运行程序需要加载至内存中,静态库的连接方式会导致内存中出现大量重复代码

4.动态库的连接方式比较节省内存空间和磁盘资源

(一般的可执行程序都是默认动态连接的)

简单理解库的本质

库分为两部分:一个是开放的.h头文件包含各个函数的声明,另一个是的各个函数的实现,是编译后的.o文件组成的集合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/82467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用“红烧鱼”类比说明卷积神经网络CNN的概念

我们用一个生活中的例子——「厨房做红烧鱼」 的场景,来类比卷积神经网络中多层卷积核的工作过程。你会发现,卷积层就像厨房里分工明确的厨师团队,逐步处理食材,最终完成一道复杂的菜品。 🐟 生活案例:厨房…

uniapp与微信小程序开发平台联调无法打开IDE

经测试属于网络问题。本机需要联网。否则会出现Hbuilder运行微信小程序到模拟器时无法打开 微信开发者工具 这个页面出不来会一直显示异常。这期间微信小程序开发工具的端口是通的 需要先联网

内网穿透之Linux版客户端安装(神卓互联)

选择Linux系统版本 获取安装包 :https://www.shenzhuohl.com/download.html 这里以Ubuntu 18.04为例,其它版本方法类似 登录Ubuntu操作系统: 打开Ubuntu系统终端,更新版本 apt-get update 安装运行环境: 安装C 运…

硬件学习笔记--66 MCU的DMA简介

DMA(Direct Memory Access,直接存储器访问)是MCU中一种重要的数据传输机制,它允许外设与存储器之间或存储器与存储器之间直接传输数据,而无需CPU的持续干预。 1、DMA的基本原理 1.1 核心概念: 1&#xf…

DeepSeek本地部署及WebUI可视化教程

前言 DeepSeek是近年来备受关注的大模型之一,支持多种推理和微调场景。很多开发者希望在本地部署DeepSeek模型,并通过WebUI进行可视化交互。本文将详细介绍如何在本地环境下部署DeepSeek,并实现WebUI可视化,包括Ollama和CherryStudio的使用方法。 一、环境准备 1. 硬件要…

RK3588和FPGA桥片之间IO电平信号概率性不能通信原因

1.GPIO管脚配置问题 RK3588对IO进行配置的时候,如果配置为多功能复用,没有明确IO功能,可能引起信号接收不稳定, 需要在驱动中设备树中配置管脚为GPIO功能,确保没有功能复用的干扰。 2.上下拉电阻阻值设置不当 GPIO引脚…

相机--相机标定实操

教程 camera_calibration移动画面示例 usb_cam使用介绍和下载 我使用的是USB相机,所以直接使用ros的usb_cam功能包驱动相机闭关获取实时图像,然后用ros的camera_calibration标定相机。 查询摄像机的信息 v4l2-ctl -d 0 --all的作用 命令详解&#xf…

【Kotlin】高阶函数Lambda内联函数

【Kotlin】简介&变量&类&接口 【Kotlin】数字&字符串&数组&集合 【Kotlin】高阶函数&Lambda&内联函数 【Kotlin】表达式&关键字 文章目录 函数还是属性高阶函数抽象和高阶函数实例: 函数作为参数的需求方法引用表达式更多使用场…

飞算JavaAI 炫技赛重磅回归!用智能编码攻克老项目重构难题

深夜还在排查十年前Hibernate框架埋下的N1查询隐患?跨语言迁移时发现SpringMVC控制器里的业务逻辑像一团乱麻?当企业数字化进入深水区,百万行代码的老系统就像一座随时可能崩塌的"技术债冰山"。近日,飞算科技发布JavaAI…

Linux I2C 子系统全解:结构、机制与工程实战

Linux I2C 子系统全解:结构、机制与工程实战 前言 I2C(Inter-Integrated Circuit)作为嵌入式系统和各种电子产品中最常用的串行通信总线之一,在 Linux 内核中的地位极其重要。然而,Linux I2C 子系统的分层结构、对象模…

多线程编程技术解析及示例:pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock

多线程编程技术解析及示例:pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock 摘要 本文深入解析了多线程编程中 pthread_cond_timedwait、pthread_mutex_lock 和 pthread_mutex_trylock 三个函数的功能、使用场景及注意事项,并通…

元胞自动机(Cellular Automata, CA)

一、什么是元胞自动机(Cellular Automata, CA) 元胞自动机(CA) 是一种基于离散时间、离散空间与规则驱动演化的动力系统,由 冯诺依曼(John von Neumann) 于1940年代首次提出,用于模…

Flutter面试题

Flutter架构解析 1. Flutter 是什么?它与其他移动开发框架有什么不同? Flutter 是 Google 开发的开源移动应用开发框架,可用于快速构建高性能、高保真的移动应用(iOS 和 Android),也支持 Web、桌面和嵌入式设备。。它与其他移动开发框架(如 React Native、Xamarin、原…

MySQL 如何判断某个表中是否存在某个字段

在MySQL中,判断某个表中是否存在某个字段,可以通过查询系统数据库 INFORMATION_SCHEMA.COLUMNS 实现。以下是详细步骤和示例: 方法:使用 INFORMATION_SCHEMA.COLUMNS 通过查询系统元数据表 COLUMNS,检查目标字段是否存…

golang 实现基于redis的并行流量控制(计数锁)

在业务开发中,有时需要对某个操作在整个集群中限制并发度,例如限制大模型对话的并行数。基于redis zset实现计数锁,做个笔记。 关键词:并行流量控制、计数锁 package redisutilimport ("context""fmt""…

从线性方程组角度理解公式 s=n−r(3E−A)

从线性方程组角度理解公式 sn−r(3E−A) 这个公式本质上是 ​齐次线性方程组解空间维度 的直接体现。下面通过三个关键步骤解释其在线性方程组中的含义: 1. ​公式对应的线性方程组 考虑矩阵方程: (3E−A)x0 其中: x 是 n 维未知向量3E−…

Docker 在 AI 开发中的实践:GPU 支持与深度学习环境的容器化

人工智能(AI)和机器学习(ML),特别是深度学习,正以前所未有的速度发展。然而,AI 模型的开发和部署并非易事。开发者常常面临复杂的依赖管理(如 Python 版本、TensorFlow/PyTorch 版本、CUDA、cuDNN)、异构硬件(CPU 和 GPU)支持以及环境复现困难等痛点。这些挑战严重阻…

解决CSDN等网站访问不了的问题

原文网址:解决CSDN等网站访问不了的问题-CSDN博客 简介 本文介绍解决CSDN等网站访问不了的方法。 问题描述 CSDN访问不了了,页面是空的。 问题解决 方案1:修改DNS 可能是dns的问题,需要重新配置。 国内常用的dns是&#x…

使用tortoisegit连接远程仓库进行克隆、拉取、获取、提交、推送、新建/切换分支、重命名、删除的一套流程(附带巨全面的git命令)

1.整备好tortoisegit工具。 2.新建一个文件夹,并进入这个文件夹后鼠标右击(选择克隆): 3.先去项目中拿到https地址,再填入: 4.新建分支,右击克隆到本地的项目文件: 5.推送到远程&am…

ArcGIS Pro 3.4 二次开发 - 地图创作 1

环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 ArcGIS Pro 3.4 二次开发 - 地图创作 11 样式管理1.1 如何通过名称获取项目中的样式1.2 如何创建新样式1.3 如何向项目添加样式1.4 如何从项目中移除样式1.5 如何向样式添加样式项1.6 如何从样式中移除样式项1.7 如何判断样式是否可…