【linux基础(六)】Linux中的开发工具(中)--gcc/g++

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:Linux从入门到开通⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学更多操作系统知识
  🔝🔝


在这里插入图片描述

Linux中的开发工具

  • 1. 前言
  • 2. gcc/g++的使用介绍
  • 3. 执行可执行程序
  • 4. 程序翻译的四个阶段
    • 4.1 预处理阶段
    • 4.2 编译阶段
    • 4.3 汇编阶段
    • 4.4 链接阶段
  • 5. 库函数的命名和分类(动静态库)
  • 6. 动静态库的区别与优缺点
  • 7.总结以及拓展

1. 前言

如果你不知道vim的各种用法和快捷键
请先阅读上一篇文章: yum和vim详解

现在,我们可以在Linux下编辑代码了
编辑好的文件是一个.c文件,vim不像
VS一样既可以编写代码也可以运行代码
在Linux中运行代码需要使用:gcc,g++

本章重点:

本篇文章会着重讲解gcc/g++的使用
以及程序翻译的几个过程和对应的文件
最后讲解动态库和静态库的区别和联系


2. gcc/g++的使用介绍

首先我们要明确一点:
在之前的Linux学习中谈到
Linux中不分文件后缀,所以文本文件可以
设置后缀为txt来提醒读者这是一个文本文件
也可以什么都不写

但是Linux系统不分文件后缀
不代表Linux下的各种程序不分!

今天要学习的gcc和g++就是Linux下的程序
它们是要看文件后缀的!

  • gcc: C语言编译器,只能编译C语言
  • g++: C++编译器,C/C++都可以编译

gcc/g++使用方法:

  1. 生产的可执行程序名字默认为:a.out
gcc code.c
  1. 自定义可执行程序的名字
gcc code.c -o 自定义名字
  1. 使用C99标准来编译
gcc code.c -std=99

3. 执行可执行程序

执行可执行程序:

当我们编译好程序后,会在当前目录生成一个
可执行程序,此文件通常是绿色的

在这里插入图片描述

此时我们只需要使用以下指令即可运行代码!

./a.out

注:.代表要在当前目录下找可执行文件.必须加上


4. 程序翻译的四个阶段

虽然现在已经掌握了如何编译并运行代码
但是在C/C++代码的翻译过程中还有四个
阶段值得我们去学习:

  1. 预处理阶段
  2. 编译阶段
  3. 汇编阶段
  4. 链接阶段

4.1 预处理阶段

预处理阶段要做的工作有:

  • 头文件展开
  • 去掉注释
  • 条件编译
  • 宏替换

那么预处理阶段过后还是C语言吗?
现在我们用Linux指令来查看一下:

使用指令: gcc -E csdn.c -o csdn.i

指令解释:将程序停留在预处理过程后,生成.i文件

在这里插入图片描述
现在我们使用vim编辑器打开.i件:

预处理阶段

可以发现,我们写的代码在最下面
然而上面还有几百行其实就是头文件展开
所谓头文件展开就是:
将头文件的内容拷贝到当前文件
在头文件中有许多空行,这是
因为原先的头文件有注释,此时注释已经没了

注:其他工作大家可自行去验证


4.2 编译阶段

编译阶段的主要工作是:

  • 将C语言翻译为汇编代码

编译阶段过后,就不是C语言了!
现在我们用Linux指令来查看一下:

使用指令: gcc -S csdn.i -o csdn.s

指令解释:将程序停留在编译过程后,生成.s文件

注:可以由.c文件直接使用以上指令变成.s文件

在这里插入图片描述

使用vim编辑器打开.s文件:

B站视频描述

可以发现,现在的汇编代码
如果没有了解过是很难读懂的


4.3 汇编阶段

汇编阶段的主要工作是:

  • 将汇编代码变成可重定位二进制文件

汇编阶段过后,文件存放的是二进制信息!
现在我们用Linux指令来查看一下:

使用指令: gcc -c csdn.s -o csdn.o

指令解释: 将程序停留在汇编过程后,形成.o文件

注:这里也可以用.c或.i文件形成.o文件

在这里插入图片描述

此时使用vim打开文件是乱码
可以使用指令od查看二进制文件:

B站视频描述


4.4 链接阶段

链接阶段比较复杂,它大致的流程是这样的:

.o文件 + 系统库 = 可执行程序

在本篇文章的后半段讲完动静态库后再解释!


5. 库函数的命名和分类(动静态库)

我们在写C语言代码时使用的printf函数
并没有自己实现,然而在stdio.h头文件中
也只有printf函数的说明,那么此函数的
实现是在哪里实现的呢?

引出今天的新内容
查看一个可执行程序依赖的第三方库

使用指令: ldd 可执行程序名

在这里插入图片描述

可以发现,在路径lib64里有一个文件叫libc.so.6
这个就是刚刚的C语言程序所要依赖的库

对于库名字的解释:

在这里插入图片描述

可见,libc.so.6实际上就是C的标准库!

拓展:Linux和Windows下动静态库命名区别:

  • Linux下: .so 是动态库 .a 是静态库

  • Windows下: .ddl 是动态库 .lib 是静态库

现在我们就可以理解链接过程了
链接过程就是将.o文件和动/静态库结合的过程


6. 动静态库的区别与优缺点

通俗的来讲,动态库类似于网吧的电脑
而静态库类似于自己家里的电脑

它们的区别是:

  • 动态库是共享库,通过函数地址来关联程序
  • 静态库是私有库,可以独立运行

动态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以动态链接的方式关联起来

静态库: 是C/C++或其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码拷贝至自己的可执行程序当中!

说白了,静态库是将所有代码拷贝过来
而动态库是去找函数的地址调用此函数

动静态库的优缺点:

  • 动态库: 优点:形成的可执行程序体积较小,节省资源
    缺点:要找函数地址,会稍慢一点,并且有强依赖性

  • 静态库: 优点:无视库,可以独立运行
    缺点: 体积太大,浪费资源

我们在编译代码时,默认使用的是动态库
并且Linux下绝大多数库都是动态库!

如果你想使用静态库编译代码

使用指令: gcc code.c -static


7.总结以及拓展

总的来说gcc,g++这两个编译器并不难
掌握它们就需要学会使用一些特殊的指令
这里列出一些gcc常用的指令
大家可以下来自己尝试:

在这里插入图片描述

拓展: 计算机语言发展史和C/C++的翻译过程

众所周知,计算机只认识二进制码是因为
计算机内的硬件元器件只认识二进制(正电/负电)
最开始和计算机交流是用二进制进行交流
最经典的用具就是二进制打孔胶带

在这里插入图片描述

科学家觉得用二进制交流非常不方便!
于是发明了汇编语言,汇编语言和汇编编译器
都是用二进制码写的,当这一过程被完善后
就可以用汇编语言来重新编写汇编编译器了!

有了汇编语言后陆陆续续又发展了许多语言
最经典的莫过于C语言!然而C语言是用汇编
代码编写的,C语言的编译器也是用汇编代码写的
当这一过程成熟后,就可以用C语言程序编写
C语言的编译器了,于是语言才慢慢发展起来

结论:

通过了解C语言的历史我们发现
C语言的翻译过程正是它的历史过程!
先从C语言翻译为汇编,再从汇编翻译为二进制
因为大佬总是懂得站在巨人的肩上,有前人
编写了从汇编到二进制的代码,那么我们就
不用再写直接从C语言到二进制的代码了

一是方便了科学家本身,二是让我们勿忘历史!


🔎 下期预告:Linux开发工具(下) 🔍

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

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

相关文章

selenium 网页自动化-在访问一个网页时弹出的浏览器窗口,我该如何处理?

前言 相信大家在使用selenium做网页自动化时,会遇到如下这样的一个场景: 在你使用get访问某一个网址时,会在页面中弹出如上图所示的弹出框。 首先想到是利用Alert类来处理它。 然而,很不幸,Alert类处理的结果就是没…

LeetCode——动态规划篇(二)

刷题顺序及思路来源于代码随想录,网站地址:https://programmercarl.com 343. 整数拆分 - 力扣(LeetCode) 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整…

【转存】从 JMM 透析 volatile 与 synchronized 原理

在面试、并发编程、一些开源框架中总是会遇到 volatile 与 synchronized 。synchronized 如何保证并发安全?volatile 语义的内存可见性指的是什么?这其中又跟 JMM 有什么关系,在并发编程中 JMM 的作用是什么,为什么需要 JMM&#…

ArcGIS 10.2安装教程!

软件介绍:ArcGIS是一款专业的电子地图信息编辑和开发软件,提供一种快速并且使用简单的方式浏览地理信息,无论是2D还是3D的信息。软件内置多种编辑工具,可以轻松的完成地图生产全过程,为地图分析和处理提供了新的解决方…

PPT 生成整数序列字典序的r-组合算法

生成整数序列字典序的r-组合算法 一、PPT效果展示二、问题2.1 简述2.2 算法简述2.3 例子 三、PPT实现 一、PPT效果展示 二、问题 2.1 简述 给定一个整数序列 (1,2,3,…n),输出其所有字典序的r-组合,注意事项&#xf…

QT子线程或自定义类操作访问主界面UI控件的几种方法

前言 QT创建窗体工程,一般在MainWindow或Dialog类里可以直接通过ui指针访问控件,但是添加新的类后又如何访问呢,可以通过以下几种方式: 将ui指针公开后直接访问 (1)例如有个自己定义的类CustomCl…

【Redis】深入探索 Redis 的数据类型 —— 列表 List

文章目录 一、List 类型介绍二、List 类型相关命令2.1 LPUSH 和 RPUSH、LPUSHX 和 RPUSHX2.2 LPOP 和 RPOP、BLPOP 和 BRPOP2.3 LRANGE、LINDEX、LINSERT、LLEN2.4 列表相关命令总结 三、List 类型内部编码3.1 压缩列表(ziplist)3.2 链表(lin…

《向量数据库指南》——Milvus Cloud云原生分布式向量数据库的优势有哪些?

首先解释一下什么是分布式,什么是云原生。分布式的概念相对容易理解,就是系统的各个组件在不同的节点上进行协作和分工,以实现更大规模和更高性能的处理。而云原生并不仅仅指运行在 Kubernetes(K8s)上或在公有云上的服务。在我的理解中,分布式云原生意味着系统首先是一个…

【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数

在Java编程中,可变参数是一项强大的功能,它允许你编写更加灵活的方法,接受不定数量的参数。本文将详细解释Java可变参数的用法、语法以及最佳实践。 什么是可变参数? 可变参数是Java 5引入的一项功能,它允许你在方法…

汇总selenium利用xpath等找网页节点的方法

一、通过子节点定位父节点&#xff0c;模拟建立一个test.html <!--子节点定位父节点--> <html> <body> <div id"A"><div>定位到这里1<div>定位到这里2<div>定位到这里3<div id"C">子节点</div><…

贝叶斯分位数回归、lasso和自适应lasso贝叶斯分位数回归分析免疫球蛋白、前列腺癌数据...

原文链接&#xff1a;http://tecdat.cn/?p22702 贝叶斯回归分位数在最近的文献中受到广泛关注&#xff0c;本文实现了贝叶斯系数估计和回归分位数&#xff08;RQ&#xff09;中的变量选择&#xff0c;带有lasso和自适应lasso惩罚的贝叶斯&#xff08;点击文末“阅读原文”获取…

vue基础知识十:Vue中组件和插件有什么区别?

一、组件是什么 回顾以前对组件的定义&#xff1a; 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念&#xff08;组件&#xff09;来实现开发的模式&#xff0c;在Vue中每一个.vue文件都可以视为一个组件 组件的优势 降低整个系统的耦合度&#xff0c;在保持接口不…

【洛谷 P1364】医院设置 题解(图论+深度优先搜索)

医院设置 题目描述 设有一棵二叉树&#xff0c;如图&#xff1a; 其中&#xff0c;圈中的数字表示结点中居民的人口。圈边上数字表示结点编号&#xff0c;现在要求在某个结点上建立一个医院&#xff0c;使所有居民所走的路程之和为最小&#xff0c;同时约定&#xff0c;相邻接…

C#,数值计算——64位哈希表的计算方法与实现代码

1 文本格式 using System; namespace Legalsoft.Truffer { public class HashAll { public HashAll() { } /// <summary> /// Pseudo-DES hashing of the 64-bit word(lword, rword). Both 32-bit arguments /// are …

GDB之调试系统接口syscall(九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

JavaScript 知识扫盲

JavaScript 知识扫盲 写在前面一、JavaScript 写入形式二、常用输入输出三、JS 是动态类型语言四、运算符五、数组1、数组创建2、获取和修改数组元素3、新增元素4、删除元素 六、函数七、对象1、对象的创建2、属性方法的使用 八、JavaScript 和 Java 对比九、事件1、常见事件2、…

Kubernetes(k8s)上搭建nacos集群

Kubernetes上搭建nacos集群 环境准备Kubernetes准备数据库准备 部署nacos集群官方镜像地址创建configmap创建部署文件根据yaml资源清单文件部署nacos 环境准备 Kubernetes准备 你需要准备一个Kubernetes集群&#xff0c;如图我的集群已经准备完毕&#xff1a; 数据库准备 …

【蓝桥杯选拔赛真题60】Scratch旋转风车 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

目录 scratch旋转风车 一、题目要求 编程实现 二、案例分析 1、角色分析

【脑机接口论文与代码】 基于自适应FBCCA的脑机接口控制机械臂

Brain-Controlled Robotic Arm Based on Adaptive FBCCA 基于自适应FBCCA的脑机接口控制机械臂论文下载&#xff1a;算法程序下载&#xff1a;摘要1 项目介绍2 方法2.1CCA算法2.2FBCCA 算法2.3自适应FBCCA算法 3数据获取4结果4.1脑地形图4.2频谱图4.3准确率 5结论 基于自适应FB…

Spring底层的核心原理解析

这篇文章大致讲解一下spring的整个执行流程&#xff0c;也就是在我们脑子里面建立一个笼统的概念 spring如何创建一个容器呢 容器里面是对象 上面就是利用AnnotationConfigApplicationContext这个对象&#xff0c;然后传入了一个配置类的字节码对象给我们创建一个Spring容器&am…