【linux系统编程】编辑器gcc/g++

目录

Linux下的编辑器

介绍:

1,编辑器gcc/g++

1-1,系统的编译过程

1-2,预处理过程

1-3,编译过程

1-4,汇编过程

1-5,链接过程


Linux下的编辑器

介绍:

        Linux系统下可支持很多高级语言的编辑,不同的编辑工具对应不同的语言。本章,我们重点介绍C语言的编辑器 gcc 和C++的编辑器 g++,其中g++也可编辑C语言的文本,但gcc不可编辑C++的文本。

1,编辑器gcc/g++

        我们都知道,文件的编译过程需要经过预处理、编译、汇编、链接过程,直接 gcc [文件] 将会直接一次性执行完编辑文本的过程,形成可执行文件。

        上图中我们形成的可执行文件是系统默认命名的,使用 gcc code.c -o code.exe 或 gcc -o code.exe code.c 都将可执行文件命名为code.exe,即凡是跟在 -o 选项后面的名称都是可执行文件的命名。

1-1,系统的编译过程

        众所周知,计算机的语言发展先是从二进制语言到汇编语言,然后不断发展,有了许多的高级语言,因此,高级语言在计算机内部执行时,需要将其翻译成汇编语言,然后从汇编语言翻译成二进制语言,因为发展过程都是要先有语言然后才有了编译器。

        当对文本进行编辑工作时,首先,在预处理过程中,系统会将头文件展开(本质是将头文件内容拷贝至源文件)、去掉文本中的注释、进行宏的替换、条件编译等。下一步进入编译工作时,系统会将高级语言编译成汇编语言,然后进入汇编阶段中,系统将汇编语言编译成二进制文件,此二进制文件称为 “可重定位目标二进制文件” ,注意,此时的二进制文件是不可执行的。因为此时的二进制文件还没有与高级语言中特定的库文件形成关联,即没有联系,而链接过程就是使用标准库文件,将形成的二进制文件与高级语言标准库文件中的代码形成关联,使系统能够识别其中代码的功能。

库文件:

        库文件是预先编译好的函数功能的集合,可以将用户写好的程序打包成一个整体,当其他模块或用户使用时,只需要这个库文件即可,不需要源代码文件。其中,库文件主要分为静态库和动态库,程序在使用库时使用静态链接或动态链接进行静态库或动态库的关联。Linux中静态库文件以 .a 后缀名,动态库文件以 .so 后缀名;Windows中静态库文件以 .lib 为后缀名,动态库文件以 .dll 为后缀名。

        静态库的特点是程序在编译连接的过程当中,编译器从库文件中取得所需代码,复制到生成的可执行文件中。因此静态库是程序在链接阶段被复制到程序当中,和程序的执行过程没有关系。

        动态库(也称为共享库)的特点是在程序运行时由系统动态加载到内存中,程序在使用时直接关联。因此,动态库可以被多个程序共享,同时只占用一份内存空间,提高了内存的使用效率。

        我们可使用 ldd 指令来观察可执行文件所依赖的库文件。

[zhu@zhujunhao ~]$ ldd code   #查看C语言中可执行文件code所依赖的库文件
    linux-vdso.so.1 =>  (0x00007ffd9b12a000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fde6069b000)  #code依赖动态库/lib64/libc.so.6
    /lib64/ld-linux-x86-64.so.2 (0x00007fde60a69000)

        /lib64/libc.so.6这个文件就是C语言标准动态库,标准静态库是/lib64/libc.a,因此在Linux中,我们可直接使用C语言。其它语言也同理,平台要支持一种语言的开发,就必须要提前在系统中安装这种语言的标准头文件和库文件。

1-2,预处理过程

        当我们只想要查看预处理生成的内容时,使用 gcc -E [目标文件] 可在直接显示预处理处理后生成的数据,使用 gcc -E [目标文件] -o [文件] (这里选项不分前后顺序)会将源文件处理后的数据放入 [文件] 中。当不存在 [文件] 时,系统会自动创建此文件。这里的 -E 表示系统将预编译过程处理完后停止。

[zhu@zhujunhao ~]$ gcc -E code.c -o code.i   #将 code.c 文件经预处理后生成的数据放入 code.i 中
[zhu@zhujunhao ~]$ ll
total 36
-rw-rw-r-- 1 zhu zhu    89 Dec  6 08:46 code.c
-rw-rw-r-- 1 zhu zhu 25606 Dec  6 08:47 code.i
-rw-rw-r-- 1 zhu zhu   827 Dec  5 14:52 install.sh

        在预处理过程,我们可使用 -D [宏名称] 自动将宏加入源文件中,在预处理阶段也会将其一并处理。这里要注意,这里的指令添加只是暂时将其添加,再次进入文本后可观察到没有此宏。

[zhu@zhujunhao ~]$ gcc code.c -DSETVECTOR=1 -o code.exe

[zhu@zhujunhao ~]$ ./code.exe
have SETVECTOR=1      #可发现存在此宏

预编译过程将添加的宏进行替换,但在其它阶段不可,因为只有在预编译过程中才处理宏

[zhu@zhujunhao ~]$ gcc -E code.c -D SETVECTOR -o code.i  

        因此,通过以上可发现,我们在系统编程的过程中,我们可实现自己代码和编译器指令的动态裁剪。

1-3,编译过程

        当我们只想要观看编译处理后的内容时,需使用  -S 选项,使用方法跟预处理使用的语法和方法一样,即:gcc -S [目标文件] -o [文件](这里选项不分前后顺序),将处理完的数据放到 [文件] 中,不同的是,[目标文件] 可以是C语言源文件,也可以是预处理后的文件。-S 表示系统将编译过程处理完后就停止。

[zhu@zhujunhao ~]$ gcc -E code.c -o code.i     #预处理后的文件code.i

[zhu@zhujunhao ~]$ gcc -S code.c -o code.s    #处理C语言源文件,形成文件code.s

[zhu@zhujunhao ~]$ gcc -S code.i -o code.s1   #处理预处理的文件,形成文件code.s1

        此过程结束后将会形成汇编语言,即系统调用汇编编译器形成汇编语言。

1-4,汇编过程

        只观看汇编处理后的数据对应的选项为 -c ,用法一样,指令为 gcc -c [目标文件] -o [文件](这里选项不分前后顺序),将汇编形成的二进制数据放入 [文件] 中,其中 [目标文件] 可以是C语言源文件,可以是预处理后的文件,可以是编译过程中形成的汇编文件。-c 表示当系统将汇编过程处理完后就停止。

[zhu@zhujunhao ~]$ gcc -c code.c -o code.o  #处理C语言源文件code.c

[zhu@zhujunhao ~]$ gcc -c code.i -o code.o   #处理预处理后的文件code.i

[zhu@zhujunhao ~]$ gcc -c code.s -o code.o  #处理编译后的汇编文件code.s

        上面的形成的 code.o 文件就是二进制文件。

1-5,链接过程

        链接是系统处理的最后一步,这里不需要任何选项,直接 gcc 编译即可,即 gcc [目标文件] -o [文件] (这里选项不分前后顺序),这里形成的文件就是将二进制文件与标准库文件链接后的可执行文件。这里表示的是系统直接处理 [目标文件] ,形成可执行文件。

[zhu@zhujunhao ~]$ gcc code.o -o code    #将二进制文件code.o链接

        可发现,这就是我们平常直接将源文件形成可执行文件的指令。即链接指令。

        链接过程中,系统默认使用动态链接,C语言的动态库在 /lib64/libc.so.6 文件下,而C++的动态库在  /lib64/libstdc++.so.6 文件下,其中,使用 -static 可在链接时改为静态链接,这里要注意的是有些系统默认可能没有安装静态库。我们需要去安装静态库,安装C和C++的静态库指令如下:

[root@zhujunhao ~]# yum install -y glibc-static libstdc++-static   

glibc-static 是C语言的静态库         libstdc++-static是C++的静态库

        其中,C语言安装后的静态库在 /lib64/libc.a 文件下,C++的静态库在 /lib64/libstdc++.a 文件下。

        链接过程使用静态链接指令如下:

[zhu@zhujunhao ~]$ gcc code.c -o code-static -static

[zhu@zhujunhao ~]$ ldd code-static
    not a dynamic executable    #查看后可发现链接的不是动态库,即链接静态库

        g++的使用都与gcc一样,注意的是系统原本没有安装 g++ 编译器,在 CentOS 版本下,安装g++ 相关的指令是:yum install gcc-c++

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

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

相关文章

生成式AI赋能千行百业加速创新,2023亚马逊云科技re:Invent行业盘点

2023亚马逊云科技re:Invent全球大会已于上周圆满闭幕,在本次大会中,亚马逊云科技又为大家带来了很多功能/项目迭代更新,也重磅发布了很多全新的功能。今天从行业视角来盘点回顾哪些重磅发布适用于垂直行业客户,以及面向汽车、制造…

MySQL 数据库如何实现 XA 规范?

本文我们来讨论 MySQL 的 XA 规范有哪些应用相关的内容。 MySQL 为我们提供了分布式事务解决方案,在前面的内容中提到过 binlog 的同步,其实是 MySQL XA 规范的一个应用,那么 XA 规范是如何定义的,具体又是如何应用的呢&#xff…

Si24R03—低功耗 SOC 芯片(集成RISC-V内核+2.4GHz无线收发器)

Si24R03是一款高度集成的低功耗SOC芯片,其集成了基于RISC-V核的低功耗MCU和工作在2.4GHz ISM频段的无线收发器模块。 MCU模块具有低功耗、Low Pin Count、宽电压工作范围,集成了13/14/15/16位精度的ADC、LVD、UART、SPI、I2C、TIMER、WUP、IWDG、RTC等丰…

Linux:进程优先级与命令行参数

目录 1.进程优先级 1.1 基本概念 1.2 查看系统进程 1.3 修改进程优先级的命令 2.进程间切换 2.1 相关概念 2.2 Linux2.6内核进程调度队列(了解即可) 3.命令行参数 1.进程优先级 1.1 基本概念 cpu资源分配的先后顺序,就是指进程的优…

MySql复习笔记03(小滴课堂) 事务,视图,触发器,存储过程

mysql 必备核心知识之事务的详细解析: 创建一个数据库表: 添加数据并开启事务。 添加数据并查询。 登录另一台服务器发现查不到这个表中的数据。 这是因为事务开启了,但是没有提交,只是把数据存到了内存中,还没有写入…

海外地区开启IPV6无法访问服务器问题

前言 最近有海外地区的用户反馈无法访问公司的网络,无法下载应用和系统进行升级。了解到浏览器可以正常访问公司域名,谷歌,油管等都能正常使用。日志分析GET请求服务器数据时没有得到应答,最终查询网络相关修改确认与网络IPV6有关…

【Jeecg Boot 3 - 保姆级】第1节 docker + redis + nginx + redis一键安装启动

一、前言 ▶ JEECG-BOOT 开源版难以吃透的原因 ▶ 为了针对上面痛点,笔者做了如下安排 ▶ 你能收获什么 二、效果(第一节效果) ▶ 启动后端 > 日志 > 接口文档 ▶ 启动前端 三、准备工作 四、实战 ▶ 1、服务器安装 Stag…

C#注册表技术及操作

目录 一、注册表基础 1.Registry和RegistryKey类 (1)Registry类 (2)RegistryKey类 二、在C#中操作注册表 1.读取注册表中的信息 (1)OpenSubKey()方法 (2)GetSubKeyNames()…

天池SQL训练营(三)-复杂查询方法-视图、子查询、函数等

-天池龙珠计划SQL训练营 SQL训练营页面地址:https://tianchi.aliyun.com/specials/promotion/aicampsql 3.1 视图 我们先来看一个查询语句(仅做示例,未提供相关数据) SELECT stu_name FROM view_students_info;单从表面上看起来…

unity 2d 入门 飞翔小鸟 死亡闪烁特效(十三)

一、c#脚本 using System.Collections; using System.Collections.Generic; using UnityEngine;public class Bling : MonoBehaviour {public Texture img;public float speed;public static bool changeWhite false;private float alpha0f;// Start is called before the fi…

shell基本知识

Linux 系统中 shell 的基本知识 1 什么是 shell Shell 是一种命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序。用户可以用 shell 来启动、挂起、停止甚至是编写一些程序。 2 Linux 启动过程 Linux 系统的启动过程可以概括为…

【深度挖掘Java性能调优】「底层技术原理体系」深入探索Java服务器性能监控Metrics框架的实现原理分析(Counter篇)

目录 前提概要监控工作可以分为四个部分 监控开发任务Metrics中的基础数据类型计数器(Counter)统计 API 访问中异常(1000/1500)的次数统计 API 的调用量统计特定事件发生的次数Counter的底层原理基础 (Base) 计数器单元 (Cell) 数…

【华为数据之道学习笔记】2-建立企业级数据综合治理体系

数据作为一种新的生产要素,在企业构筑竞争优势的过程中起着重要作用,企业应将数据作为一种战略资产进行管理。数据从业务中产生,在IT系统中承载,要对数据进行有效治理,需要业务充分参与,IT系统确保遵从&…

mmdetection里的测速脚本

由于大论文里需要对各个算法进行测速,因此抛开官方文档的使用说明,记录一下我是怎么使用mmdetection里的脚本进行测速的。 mmdetection版本:2.23.0 一、新版本benchmark.py(需要分布式) 打开tools/analysis_tools/b…

xml文本转Java对象

Java对象转String public static String toData(Object object) throws Exception {JAXBContext jc JAXBContext.newInstance(object.getClass());Marshaller m jc.createMarshaller();StringWriter output new StringWriter(2048);m.marshal(object, output);String data …

C# 任务并行类库Parallel调用示例

写在前面 Task Parallel Library 是微软.NET框架基础类库(BCL)中的一个,主要目的是为了简化并行编程,可以实现在不同的处理器上并行处理不同任务,以提升运行效率。Parallel常用的方法有For/ForEach/Invoke三个静态方法…

如何确认网站是否有漏洞,如何找出网站存在的漏洞,找到漏洞该如何处理

如何确认网站或者服务器是否有漏洞 判断一个网站是否是存在漏洞的方法: 1.可以借助德迅云安全漏洞扫描功能来检查漏洞。 2.打开德迅云安全首页,点击最上面导航栏中的“安全产品”。 3.滑到“漏洞扫描”,选择“产品价格”服务。 4.选择您需…

python源码,在线读取传奇列表,并解析为需要的JSON格式

python源码,在线读取传奇列表,并解析为需要的JSON格式 [Server] ; 使用“/”字符分开颜色,也可以不使用颜色,支持以前的旧格式,只有标题和服务器标题支持颜色 ; 标题/颜色代码(0-255)|服务器标题/颜色代码(0-255)|服务…

ThinkPHP如何讲链接多个数据库

为什么要使用多个数据库 数据分片: 当数据量非常大时,可能需要将数据分布在不同的数据库中,以提高查询性能。这被称为数据分片,其中不同的数据库负责存储不同范围的数据。 业务分离: 有时,一个大型项目可…

GPT-Crawler一键爬虫构建GPTs知识库

GPT-Crawler一键爬虫构建GPTs知识库 写在最前面安装node.js安装GPT-Crawler启动爬虫结合 OpenAI自定义 assistant自定义 GPTs(笔者用的这个) 总结 写在最前面 GPT-Crawler一键爬虫构建GPTs知识库 能够爬取网站数据,构建GPTs的知识库&#xf…