Linux下如何编译C/C++代码?从.c到.exe经历了什么?

news2024/12/23 19:22:47

在这里插入图片描述

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻强烈推荐优质专栏: 🍔🍟🌯C++的世界(持续更新中)
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解Linux下如何编译C/C++代码?

目录

  • 四个阶段
    • 4.1 “预处理”阶段:
    • 4.2 “编译”阶段
    • 4.3 “汇编”阶段
    • 4.4 “链接”阶段
  • 总结:

编译C语言指令: gcc + 文件名

如果不指定生成的 目标文件的文件名,默认生成的可执行文件的名字为 a.out

编译前:
在这里插入图片描述

编译后:
在这里插入图片描述

如何指定生成的 可执行文件的文件名呢?

方法一:
gcc + -o 选项 + 文件名1 +文件名2

方法二:
gcc +文件名2+ -o 选项 + 文件名1

解释:
文件名1:生成的可执行文件的文件名 (示例: hello.exe)
文件名2: 带编译的源文件 (示例: hello.c

指定生成的可执行文件的文件名:
在这里插入图片描述
编译c++代码:
首先如果没有安装g++命令,可以先安装一下。
安装g++命令:

yum install gcc-c++

编译指令:

g++ -o 生成的文件 待编译的文件

如果使用了c++11的语法,需要增加一个选项:
示例:

g++ -std=c++11 mycode.cc -o mycode.exe 

编译原理:
这里分享一篇不错的博客: .c到.exe的故事

四个阶段

在这里插入图片描述(图片来源于上推荐文章,图片稍作修改了)

4.1 “预处理”阶段:

前面我们是直接从.c文件到.exe可执行文件.

-E选项:让gcc开始执行程序翻译,到预处理结束后就停止。

指令: 以test.c为例。

gcc -E test.c -o test.i

-E选项表示,执行到预处理阶段完成后就停止,我们习惯将预处理后的文件用 .i文件命名,它里面依旧还是c代码,只不过更加“干净”了。

我们可以分别打开 test.ctest.i文件,查看预处理后会发生什么?

在这里插入图片描述

🔑vim使用小技巧:

可以在底行模式下,可以使用vs + 文件名 的方式,同时查看打开两个文件。
文件之间的切换: ctrl+w+w

在对预处理阶段, 会对.c文件主要完成以下工作:

  1. “头文件”展开: 也就是将所包含的头文件中的内容全拷贝过来。
  2. “条件编译”完成: 只保留满足条件的语句
  3. “宏”的替换: 宏只是简单的直接替换
  4. “注释”去掉: 注释语句时给人看的,编译器才不关心
    在这里插入图片描述

在学习C语言阶段,存在一个疑问:为什么“宏”不会做语法检查?
在这里插入图片描述
答案:
是在预处理阶段被直接替换的,而语法检查是在编译(下面讲解的)阶段进行的。在预处理阶段,已经被展开成了代码片段,而编译器只能看到这些展开后的代码片段,无法像对待普通代码一样进行语法检查。此外,可以使用一些编译器无法理解的语法,这也导致了无法进行语法检查。

注意:
因此,我们需要在编写宏时特别小心,遵循一定的规范和约定,以尽量避免出现语法错误和其他问题。在C++中,我们建议用const常量、enum、以及inline代替

补充小知识:
在这里插入图片描述

上面我们提到了gcc -E test.c -o test.i指令。

得到了下面的效果:
在这里插入图片描述

其实,我们也可以使用-D选项,gcc -E test.c -o test.i2 -DNUM=2可以在使用指令的同时 定义

示例:
在这里插入图片描述
虽然在源文件test.c中并没有定义 宏NUM,但是预处理以后,条件编译执行以后还是打印了 NUM那段语句, 原因是我们使用了 -D选项。

4.2 “编译”阶段

前面我已经了解了预处理阶段的工作,那么下一步就是 “编译”了

-S选项:让gcc开始执行程序翻译,到编译结束后就停止。

在这里插入图片描述
为什么会报错呢?
在这里插入图片描述

编译阶段,我们的演示代码中, 条件编译中使用了printf函数,而在函数外的语句位置区域是不认识printf函数的,导致编译器无法识别printf函数,这就导致了报错。

那为什么预处理就直接通过了呢?
因为“语法分析”和“词法分析”是在编译阶段进行的,所以在编译阶段就直接报错了。

原“演示”代码

#include <stdio.h>
#include <math.h> 
#define PI 3.14
#ifdef PI
    printf("PI被定义了!");
#endif
#ifdef NUM
    printf("NUM被定义了!");
#endif 

int main(){
    float r=0,area=0;    //圆的半径
    printf("请输入圆的半径:");
    scanf("%f", &r);
    area = PI * r * r;   //计算圆的面积
    //printf("注释的代码");
    printf("圆的面积是 %.2f\n", area);
    return 0;
}

修改后: “演示”代码

#include <stdio.h>
#include <math.h> 
#define PI 3.14

int main(){
#ifdef PI
    printf("PI被定义了!");
#endif
#ifdef NUM
    printf("NUM被定义了!");
#endif 

    float r=0,area=0;    //圆的半径
    printf("请输入圆的半径:");
    scanf("%f", &r);
    area = PI * r * r;   //计算圆的面积
    //printf("注释的代码");
    printf("圆的面积是 %.2f\n", area);
    return 0;
}

编译阶段主要完成以下工作:

  1. 语法分析
  2. 词法分析
  3. 语义分析
  4. 符号汇总

具体是怎么完成的,牛牛就不懂了,感兴趣的小伙伴可以去查阅相关资料,编译过后,我们就形成了汇编代码。

下图示例:
在这里插入图片描述

4.3 “汇编”阶段

“编译”结束了,我们得到了汇编指令,汇编指令是计算机中的基本指令,它用于控制计算机的运行和执行各种操作。这已经算是很接近底层的语言了。

啊,好累,这么麻烦,咋还有!
在这里插入图片描述

下一个选项登场:

-c选项:让gcc开始执行程序翻译,到“汇编”结束后就停止。

注意这里是小写的c哦。

编译让我们得到汇编,那汇编就是将汇编代码翻译成 机器语言。

没错就是机器语言,也就是一串右一串二进制。

在这里插入图片描述

由于二进制文件默认情况下vim也不认识,我们可以使用xxd命令+b选项,将其重定向到mycode文件中。

xxd -b test.o>mycode

在这里插入图片描述
打开后:
在这里插入图片描述

4.4 “链接”阶段

在这里插入图片描述

总结:

在这里插入图片描述

好的,本篇博客就讲解到这里了。

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

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

相关文章

百度智能小程序开发平台:SEO关键词推广优化 带完整的搭建教程

移动互联网的普及&#xff0c;小程序成为了众多企业和开发者关注的焦点。百度智能小程序开发平台为开发者提供了一站式的解决方案&#xff0c;帮助企业快速搭建并推广自己的小程序。本文将重点介绍百度智能小程序开发平台的SEO关键词推广优化功能&#xff0c;并带完整的搭建教程…

MySQL原理(三)锁定机制(1)综述

一、介绍&#xff1a; 1、锁的本质 业务场景中存在共享资源&#xff0c;多个进程或线程需要竞争获取并处理共享资源&#xff0c;为了保证公平、可靠、结果正确等业务逻辑&#xff0c;要把并发执行的问题变为串行&#xff0c;串行时引入第三方锁当成谁有权限来操作共享资源的判…

06 单目初始化器 Initializer

文章目录 06 单目初始化器 Initializer6.1 成员变量/函数6.2 初始化函数 Initialize()6.3 计算基础矩阵 F \boldsymbol{F} F 和单应矩阵 H \boldsymbol{H} H6.3.1 RANSAC 算法6.3.2 八点法计算 F \boldsymbol{F} F 矩阵: ComputeF21()6.3.3 计算基础矩阵 F \boldsymbol{F} …

基于yolov2深度学习网络的视频手部检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 输入mp4格式的视频文件进行测试&#xff0c;视频格式为1080p30. 2.算法运行软件版本 matlab2022a 3.部分核心程序 ..........................…

大数据分析案例-基于随机森林算法构建电影票房预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

软连接和硬链接

1.软连接 软连接是一个独立的文件&#xff0c;有独立的inode&#xff0c;也有独立的数据块&#xff0c;它的数据块里面保存的是指向的文件路径-------相当于windows的快捷方式 删除一个软连接 2.硬链接 所谓的建立硬链接&#xff0c;本质就是在特定目录的数据块中新增文件名和…

【大数据】Flink SQL 语法篇(三):窗口聚合(TUMBLE、HOP、SESSION、CUMULATE)

Flink SQL 语法篇&#xff08;三&#xff09;&#xff1a;窗口聚合 1.滚动窗口&#xff08;TUMBLE&#xff09;1.1 Group Window Aggregation 方案&#xff08;支持 Batch / Streaming 任务&#xff09;1.2 Windowing TVF 方案&#xff08;1.13 只支持 Streaming 任务&#xff…

sqli-labs-master靶场训练笔记(1-22|新手村)

2024.1.21 level-1 &#xff08;单引号装饰&#xff09; 先根据提示建立一个get请求 在尝试使用单个单引号测试&#xff0c;成功发现语句未闭合报错 然后反手一个 order by 得到数据库共3列&#xff0c;-- 后面加字母防止浏览器吃掉 -- 操作&#xff08;有些会&#xff09…

Java关于Excel文件的导入导出

人生如梦 荣华富贵 如木槿之花 朝荣夕逝 需求 导出&#xff1a; 能够将库表内的数据导出多个Excel表&#xff0c;并且生成一个压缩包&#xff0c;提供用户下载导入&#xff1a; 能够将一个压缩包内的多个Excel表解压&#xff0c;并获取表内的所有数据 FileUtils 工具类 publi…

GPT-SoVITS 本地搭建踩坑

GPT-SoVITS 本地搭建踩坑 前言搭建下载解压VSCode打开安装依赖包修改内容1.重新安装版本2.修改文件内容 运行总结 前言 传言GPT-SoVITS作为当前与BertVits2.3并列的TTS大模型&#xff0c;于是本地搭了一个&#xff0c;简单说一下坑。 搭建 下载 到GitHub点击此处下载 http…

【三维重建】运动恢复结构(SfM)

运动恢复结构是通过三维场景的多张图像&#xff0c;恢复出该场景的三维结构信息以及每张图片对应的摄像机参数。 欧式结构恢复(内参已知&#xff0c;外参未知) 欧式结构恢复问题&#xff1a; 已知&#xff1a;1、n个三维点在m张图像中的对应点的像素坐标 2、相机内参 求解&…

指针的深入了解6

1.回调函数 回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数传递给另一个函数&#xff0c;当这个指针被用来调用其所指向的函数 时&#xff0c;被调用的函数就是回调函数。回调函数不是由该函数的实现方直接调用&#xff0…

字符串:getline、删除子串.erase()函数、插入子串.insert()函数

getline具体用法&#xff1a; 1、函数形式 getline ( cin,字符串类型&#xff1a;变量名);//默认以换行符结束 getline (cin, 字符串类型&#xff1a;变量名, ‘指定的结束符’); //指定换行结束符 2注意事项&#xff1a; 1&#xff09;如果在使用getline()之前有使用scanf(…

Java基础--异常

异常 将程序执行中发生的不正常情况称为“异常”&#xff08;语法错误和逻辑错误不是异常&#xff09;。 异常时间分为两大类&#xff1a; 1.Error&#xff08;错误&#xff09;&#xff1a;Java虚拟机无法解决的严重问题。Error 是严重错误&#xff0c;程序会崩溃。 2.Except…

【AI视野·今日NLP 自然语言处理论文速览 第七十七期】Mon, 15 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 15 Jan 2024 Totally 57 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Machine Translation Models are Zero-Shot Detectors of Translation Direction Authors Michelle Wastl, Ja…

奥威-金蝶BI方案:企业获利能力该这样看

获利能力、偿债能力、营运能力是企业经营发展中需要密切关注的三大基础能力&#xff0c;通常可通过详细的数据分析可视化来获知。那么&#xff0c;怎么分析企业获利能力&#xff1f;奥威-金蝶BI方案做了个示范。 按年看 按月看 一般来说&#xff0c;我们会做成两张报表&#x…

代码随想录算法刷题训练营day20

代码随想录算法刷题训练营day20&#xff1a;LeetCode(654)最大二叉树、LeetCode(617)合并二叉树、LeetCode(700)二叉搜索树中的搜索、LeetCode(700)二叉搜索树中的搜索、LeetCode(98)验证二叉搜索 LeetCode(654)最大二叉树 题目 代码 import java.util.Arrays;/*** Definit…

Java面试架构篇【一览众山小】

文章目录 &#x1f6a1; 简介☀️ Spring&#x1f425; 体系结构&#x1f420; 生命周期 &#x1f341; SpringMVC&#x1f330; 执行流程 &#x1f31c; SpringBoot&#x1f30d; 核心组件&#x1f38d; 自动装配&#x1f391; 3.0升级 &#x1f505; spring Cloud Alibaba&am…

Consul容器服务自动发现和更新

目录 前瞻 什么是服务注册与发现 什么是consul Docker-consul实现过程 Docker-consul集群部署 实验准备 实验流程 前瞻 什么是服务注册与发现 服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的&#xff0c;不保障高可用性&#xff0c;也不考虑服…

web应用课——(第一讲:html基础标签)

目录 一、html文件结构 二、文本标签 三、图片 四、音频和视频 五、超链接 六、表单 七、列表 八、表格 九、语义标签 十、特殊符号 一、html文件结构 <html>标签&#xff1a;表示一个 HTML 文档的根&#xff08;顶级元素&#xff09;&#xff0c;所以它也被…