Linux--编译器-gcc/g++使用

目录

前言

1.看一段样例

 2.程序的翻译过程

1.第一个阶段:预处理

2.第二个阶段:编译

3.第三个阶段:汇编

4.第四个阶段:链接

3.程序的编译为什么是这个样子?

4. 关于编译器

5.链接(动静态链接)


前言

1.首先,我们来看一段样例(见一下)

2.见完之后,我们来看一下程序的翻译过程

3.了解一下翻译的过程为什么是这样的?再顺带谈一下编译器。

4.最后,我们要谈一下动静态链接,看一下它们的特点和区别


1.看一段样例

一段C语言代码:

(编译器为gcc)

在这里,可能你的编译器是不支持在循环体内直接定义变量的,因为编译器版本老旧,这时需要加上-std=99,让编译器支持C99。

在执行编译的时候可以加上-o ,在-o后面可以指定生成的可执行程序的名字。


一段C++代码:

注意C++文件的后缀为(.cc/.cpp/.cxx)

(编译器为g++)

如果没有g++,需要下载安装,下面是g++的安装指令:

yum install -y gcc-c++

在这里我们也要加上选项 -std = c++11

查看运行结果:

如果想指定c++可执行程序的名字,同样是使用-o选项

(注意:gcc不能编译c++的代码,但是g++可以编译c语言的代码)


 2.程序的翻译过程

使用C语言代码示例:

1.第一个阶段:预处理

说明:在这个阶段编译器会进行宏替换,去注释,头文件展开,条件编译

请看下面的代码:

接下来我们使用gcc的命令让程序在每个阶段都停下来,第一个选项(-E),在这里产生了临时文件test.i (-E的含义:从现在开始进行程序的编译,预处理完成,就停下)

在这里,我们发现,源代码中一下子多了八百多行代码,这就是因为<stdio.h>头文件展开拷贝到源文件,所以经过了预处理,头文件就没用了。(我们发现预处理阶段确实进行了宏的替换,去注释)

Linux系统中存在<stdio.h>的文件,才能进行此操作

Linux系统中所有的库:

关于条件编译(编译器在预处理阶段会对代码进行动态的裁剪):

        在C语言程序的预处理阶段,条件编译起着非常重要的作用。预处理阶段是在实际的编译之前进行的,主要目的是对源代码进行一些预处理操作,例如宏替换、头文件包含等。条件编译指令会在预处理阶段根据条件判断是否包含或排除特定的代码块,从而影响编译后生成的目标代码。

        使用条件编译指令可以根据不同的条件选择性地包含或排除特定的代码块。这样可以根据编译条件在不同情况下编译不同的代码,提高程序的灵活性和可移植性。

        

        我们在写条件编译的时候,一般会定义宏去调用,这样的方式效率是很低的,在Linux系统中,在指令界面就可以动态的向源代码添加宏,下面是一段示例:

在Linux中,使用gcc编译器时,可以通过 -D选项来定义预处理宏。当你使用 -D后跟一个宏名时,它告诉编译器在编译源代码之前定义该宏,可以选择性地为宏指定一个值。

        在下面这个例子中:我们为源代码中添加了宏 v1= 1 ,运行可执行程序之后,得到了接过条件编译的结果。

接着看v2 = 1


2.第二个阶段:编译

说明:编译阶段是将经过预处理后的源代码翻译成汇编代码的过程。编译器会将C语言源代码翻译成相应的汇编语言代码。

编译指令:-S表示从现在开始程序的编译,编译完成就停下来。

test.s:C语言代码转成的汇编语言代码。


3.第三个阶段:汇编

说明:汇编器会将汇编代码中的指令和数据转换成机器指令,并生成二进制目标文件。 汇编的结果是生成一个目标文件,通常以.o为扩展名。

编译指令:-c表示从现在开始进行程序的汇编,汇编完成就停下来

这个.o文件是不可执行的


4.第四个阶段:链接

说明:链接目标文件和链接库生成可执行程序(二进制的程序)。


3.程序的编译为什么是这个样子?

        在没有c语言的时候,都是用的二进制编程。三体电视剧中的机器上就是这种打孔纸带。有孔的地方信息可以透过去就是(1),没孔的地方就是(0)。但这种二进制是十分不方便的,还容易出错,这时候就发明了汇编语言,但觉得汇编语言还是不方便,后面就有了c语言。

想一想编译器是从哪里来的,二进制编程需要编译器吗?

        二进制当然是不用编译器的,从汇编开始我们就需要编译器了。编译器是非常不容易写的,我们是把c语言直接转成二进制容易,还是先转成汇编,再让汇编转成二进制容易?当然是后者比较容易,我们只需要将c语言转成汇编就行了,因为汇编转成二进制的过程前人已经帮忙做了(站在巨人的肩膀上),所以c编译器的核心工作只需要将c语言转成汇编就行了。

        因为历史选择了从二进制到汇编,从汇编到更高级的语言,从更高级的语言到c语言。我们编译的过程就是一个回溯历史的过程,这样的效率是最高的,所以c语言的编译是这个样子。


4. 关于编译器

先有语言还是语言的编译器

        当然是先有语言,才有编译器。最早的汇编语言的编译器是用二进制语言写的,汇编语言才能转成二进制跑起来。

编译器的自举

编译器的自举(bootstrapping)是指使用已经存在的编译器来编译自身的过程。简单来说,自举是通过一个较早版本的编译器来编译当前版本的编译器,从而生成一个新的、功能相同但可能更高效的编译器。 自举的过程通常涉及以下步骤:

1. **初始阶段**:在自举过程开始之前,需要有一个已经存在的编译器,通常是由其他编译器或者手动编写的汇编语言程序生成的。

2. **第一次编译**:使用初始阶段得到的编译器,将编译器的源代码编译成可执行文件。这个可执行文件就是一个新的、功能相同的编译器。

3. **第一次自举**:使用第一次编译得到的新编译器,将编译器的源代码再次编译成可执行文件。这一次编译的目标是生成一个和第一次编译得到的新编译器完全相同的新编译器。

4. **迭代自举**:重复进行自举过程,使用新生成的编译器来编译自身的源代码,生成更高效的新版本编译器。这个过程可以多次迭代,每次都会产生一个新的编译器版本,直到达到所需的性能和功能。

        通过自举,编译器可以逐步改进和优化自身,生成更高效的版本。自举的过程可以确保编译器的正确性,因为每个新版本的编译器都是由之前版本编译而来,保证了功能的一致性。

        需要注意的是,自举过程的初始阶段需要使用其他编译器或者手动编写的汇编语言程序,以便启动自举过程。自举是编译器开发和维护中重要的技术,它使得编译器可以自我改进和更新,为编程语言的发展提供了基础。


5.链接(动静态链接)

是什么?
我们的程序和库结合的过程,语言是一定要有自己的标准库的。

(安装开发环境:安装语言的标准库+头文件)

标准库通常包括各种数据结构、算法、输入输出、文件操作、网络通信等常用功能,以帮助开发人员更高效地编写程序。

在Linux中,ldd加上可执行程序,就可以查到该执行程序依赖了什么库

为什么要有链接?

1.让开发站在巨人的肩膀上 2.提高开发的效率

怎么做的?

在Linux系统中,分为两种库,动态库:.so  静态库:.a(动态链接,静态链接)

静态链接
特点:在生成可执行文件的时候(链接阶段),把所有需要的函数的二进制代码都包含到可执行文件中去。因此,链接器需要知道参与链接的目标文件需要哪些函数,同时也要知道每个目标文件都能提供什么函数,这样链接器才能知道是不是每个目标文件所需要的函数都能正确地链接。如果某个目标文件需要的函数在参与链接的目标文件中找不到的话,链接器就报错了。目标文件中有两个重要的接口来提供这些信息:一个是符号表,另外一个是重定位表。
优点:在程序发布的时候就不需要的依赖库,也就是不再需要带着库一块发布,程序可以独立执行。
缺点:程序体积会相对大一些。
如果静态库有更新的话,所有可执行文件都得重新链接才能用上新的静态库。
动态链接
特点: 在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。
优点: 多个程序可以共享同一段代码,而不需要在磁盘上存储多个拷贝。
缺点: 由于是运行时加载,可能会影响程序的前期执行性能。

下面是同一个程序在不同链接下的内存对比,很显然静态链接的内存大小是远大于动态链接

 

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

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

相关文章

Three.js学习7:dat.GUI 参数控制

-----------------------------华丽的分割线--------------------- 相关代码均已上传到 gitee 中&#xff1a;myThree: 学习 Three.js &#xff0c;努力加油~&#xff01; Gitee 静态演示地址&#xff1a;Three JS 演示页面 -----------------------------华丽的分割线------…

TCP_IP(6)

网络层 在复杂的网络环境中确定一个合适的路径. IP协议 与TCP协议并列,都是网络体系中最核心的协议. 基本概念 主机:配有IP地址,但是不进行路由控制的设备; 路由器:即配有IP地址,又能进行路由控制; 节点:主机和路由器的统称; 协议头格式 4位版本号(version):指定IP协议的版…

【面试】盘点10个高频的前端算法题,你全都会了吗?

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 现在前端的面试中&#xff0c;算法出现的频率越来越高了&#xff0c;大厂更是必考算…

字符输入/输出和输入验证 DAY19

文章目录 前言一、单字符I/O二、缓冲区为什么要引入缓冲区&#xff1f;文件结尾补充**注意几点** 重定向和文件重定向输入cmd是什么&#xff1f;重定向输出组合重定向小试牛刀&#xff1a;文件输出 创建更友好的用户界面使用缓冲输入 如果您发现文章有错误请与我留言&#xff0…

STM32,嵌入式系统中的I2C协议

I2C协议——读写EEPROM 关注我&#xff0c;共同交流&#xff0c;一起成长 前言一、协议简介二、I2C特性及架构三、通信过程 前言 这是一种主要用于集成电路和集成电路&#xff08;IC&#xff09;通信&#xff0c;计算机中复杂的问题大多数就是用分层来进行解决&#xff0c;这个…

OpenAI 文生视频大模型Sora,看完别说WC啊

OpenAI&#xff0c;发布了他们的文生视频大模型Sora&#xff08;Sora 是一个 AI 模型&#xff0c;可以根据文本指令创建现实且富有想象力的场景&#xff09; 来感受下震撼视觉冲击&#xff0c;看看你有没有说WC… 地址&#xff1a;sora 提示&#xff1a;一位时尚女性走在充满…

51单片机项目(30)——基于51单片机的心率血氧脉搏检测的proteus仿真

1.功能设计 可以测量脉搏、心率、血氧浓度、体温&#xff0c;并且实时显示在LCD1602屏幕上&#xff0c;&#xff08;第一行是体温血氧&#xff0c;第二行是心率脉搏&#xff09;。 &#xff08;需要完整源文件的&#xff0c;直接看最后一节&#xff09; 另外&#xff0c;还…

开源软件的影响力:塑造数字世界的无形之手

随着科技的飞速发展&#xff0c;开源软件已经成为了推动数字世界发展的重要力量。它不仅改变了软件开发的传统模式&#xff0c;还对整个科技行业乃至社会产生了深远的影响。在这篇文章中&#xff0c;我们将探讨开源软件的影响力以及它如何塑造我们的数字世界。 一、开源软件的…

蓝桥杯电子类单片机提升一——超声波测距

前言 单片机资源数据包_2023 一、超声波测距原理 二、超声波测距的应用 1.超声波的发射 2.单片机知识补充&#xff1a;定时器 3.超声波的接收与计时 4.距离的计算 1&#xff09;定时器1为16位自动重载&#xff0b;1T11.0592MHz 2&#xff09;定时器1为16位自动重载&am…

Peter算法小课堂—哈希与哈希表

额……字符串我们是第一次学&#xff0c;给大家铺一些基础的不能再基础的基础&#xff0c; 字符串比较大小 字符串大小的比较&#xff0c;不是以字符串的长度直接决定&#xff0c;而是从最左边第一个字符开始比较&#xff0c;大者为大&#xff0c;小者为小&#xff0c;若相等…

[01] Vue2学习准备

目录 vue理解创建实例插值表达式 {{}}响应式特性 vue理解 Vue.js 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 创建实例 准备容器 <div id…

嵌入式中I2C 相关的硬件问题汇总及死锁解决办法

本文主要介绍如何解决I2C设备硬件设计上的各种问题&#xff0c;希望对大家有所帮助&#xff01; 关于I2C协议详细的讲解&#xff0c;可以参考之前的推文&#xff1a;全面解析 I2C 通信协议 一般情况下&#xff0c; i2c 设备焊接没什么问题&#xff0c;按照设备手册一步步来&a…

Github 2024-02-15 开源项目日报 Top9

根据Github Trendings的统计&#xff0c;今日(2024-02-15统计)共有9个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量TypeScript项目4Python项目2Solidity项目2Rust项目1JavaScript项目1Go项目1C项目1 Terraform: 以安全和可预测…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——JAVA

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 1. Java 1. 和 equals的区别 比较基本数据类型是比较的值&#xff0c;引用数据类型是比较两个是不是同一个对象&#xff0c;也就是引用是否指向同 一个对象&…

[职场] 优质简历怎么做 #学习方法#笔记

优质简历怎么做 简历是求职的“敲门砖”&#xff0c;直接影响着求职成败。然而&#xff0c;不少求职者对简历不太重视&#xff0c;认为简历就是写自己的经历。因此&#xff0c;在招聘现场&#xff0c;常会看到这样的简历&#xff1a;有的是从某招聘网站直接下载而来&#xff0c…

kali无线渗透之用wps加密模式破解出wpa模式的密码12

WPS(Wi-Fi Protected Setup&#xff0c;Wi-Fi保护设置)是由Wi-Fi联盟推出的全新Wi-Fi安全防护设定标准。该标准推出的主要原因是为了解决长久以来无线网络加密认证设定的步骤过于繁杂之弊病&#xff0c;使用者往往会因为步骤太过麻烦&#xff0c;以致干脆不做任何加密安全设定&…

基于FPGA的OFDM基带发射机的设计与实现

文章目录 前言一、OFDM描述二、本系统的实现参照 1.IEEE 802.11a协议主要参数2.不同调制方式与速率 3. IFFT映射关系4. IEEE 802.11a物理层规范5. PPDU帧格式三、设计与实现 1.扰码2.卷积编码与删余3.数据交织4.符号调制5.导频插入6.IFFT变换 7.循环前缀&加窗8.训练序列生成…

LocaSpace Viewer图新地球 4.4.9工程版授权

LocaSpace Viewer图新地球是一个独特的三维数字地球软件&#xff0c;它不用安装&#xff0c;且是一个轻量级的软件&#xff0c;永久授权激活&#xff0c;没有功能方面的限制&#xff0c;在这里&#xff0c;你可以根据需要进行各种操作&#xff0c;如获取多种在线地图资源&#…

Kubernetes安装部署 2

Kubeadm创建集群 如上所示&#xff0c;在阿里云的香港地域的ECS服务器上拉取下载Kubernetes官方提供的容器镜像 如上所示&#xff0c;在阿里云的香港地域的ECS服务器保存镜像到本地 Node A服务器的IP地址&#xff1a;192.168.0.130 端口号6443开放、部署Docker容器引擎、支持cr…

linux系统zabbix监控分布式监控的部署

分布式监控 服务器安装分布式监控安装工具安装mysql导入数据结构配置proxy端浏览器配置 zabbix server端监控到大量zabbix agent端&#xff0c;这样会使zabbix server端压力过大&#xff0c;使用zabbix proxy进行分布式监控 服务器安装分布式监控 安装工具 rpm -Uvh https://…