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

在这里插入图片描述

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻强烈推荐优质专栏: 🍔🍟🌯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 “链接”阶段

在这里插入图片描述

总结:

在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习每日小知识】Model Accuracy 模型准确率

Model Accuracy 模型准确率 模型准确性是衡量机器学习 (ML) 模型基于数据做出预测或决策的能力的指标。它是用于评估 ML 模型性能的常用指标&#xff0c;可用于比较不同模型的性能或评估特定模型对于给定任务的有效性。 有多种不同的方法来衡量模型的准确性&#xff0c;具体取…

C++入门学习(二十)与或非

逻辑运算符的符号表示&#xff1a; 与&#xff1a;&&或&#xff1a;||非&#xff1a;&#xff01; a && b如果a和b都为真&#xff0c;则结果为真&#xff0c;否则为假a || b如果a和b有一个为真&#xff0c;则结果为真&#xff0c;二者都为假时&#xff0c;结…

奔驰源代码意外泄露,暴露内部敏感数据

近日&#xff0c;RedHunt 实验室的研究人员发现&#xff0c;梅赛德斯-奔驰无意中留下了可在线访问的私钥&#xff0c;暴露了内部数据&#xff0c;包括公司的源代码。目前尚不清楚数据泄露是否暴露了客户数据。 梅赛德斯-奔驰&#xff08;Mercedes-Benz&#xff09;是德国著名的…

Github 上传项目(个人令牌token)

1.点击 github头像 &#xff1a; setting -> Developer Settings -> Personal access tokens 2.在要上传的文件夹下运行以下命令&#xff1a; git init git commit -m "first commit" git branch -M main 利用以下命令模…

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷10

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

机器学习复习(4)——CNN算法

目录 数据增强方法 CNN图像分类数据集构建 导入数据集 定义trainer 超参数设置 数据增强 构建CNN网络 开始训练 模型测试 数据增强方法 # 一般情况下&#xff0c;我们不会在验证集和测试集上做数据扩增 # 我们只需要将图片裁剪成同样的大小并装换成Tensor就行 test_t…

上位机在工业控制系统中的重要作用及其与PLC的互补关系

上位机在工业控制系统中的重要作用及其与PLC的互补关系 在现代工业自动化领域&#xff0c;上位机与可编程逻辑控制器&#xff08;PLC&#xff09;都是不可或缺的重要组成部分。它们各自发挥着独特的优势&#xff0c;在实现生产过程控制、监控和数据管理中扮演了关键角色。然而&…

postgresql 查询缓慢原因分析

pg_stat_activity 最近发现系统运行缓慢&#xff0c;查询数据老是超时&#xff0c;于是排查下pg_stat_activity 系统表&#xff0c;看看有没有耗时的查询sql SELECT pid, state, query, query_start, backend_type FROM pg_stat_activity WHERE state active AND query LIK…

USB清理软件USBclean轻松清理.DS_Store,Thumbs.db,.Spotlight文件

USBclean for Mac是一款Mac上的USB清理工具&#xff0c;USBclean mac版能够帮助我们快捷方便地为你清理外部磁盘垃圾文件&#xff0c;它支持将.DS_Store, Thumbs.db, .Spotlight 以及回收站中的垃圾文件进行清理。操作也十分简单&#xff0c;只需要将要清理的外部磁盘拖拽到USB…

C++ 数论相关题目 台阶-Nim游戏

现在&#xff0c;有一个 n 级台阶的楼梯&#xff0c;每级台阶上都有若干个石子&#xff0c;其中第 i 级台阶上有 ai 个石子(i≥1 )。 两位玩家轮流操作&#xff0c;每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中&#xff08;不能不拿&#xff09;。 已经拿到地面…

踩了一堆坑,终于把微服务系统全面升级 JDK17 和 SpringBoot3 了

最近正在给自己的开源项目校园博客升级到 JDK17 以及 SpringBoot3&#xff0c;正好记录下升级和踩坑的过程&#xff0c;给大家提供一些解决方案的参考。 先说结论&#xff1a;非常推荐升级JDK17&#xff0c;成本低收益高。至于SpringBoot3.0&#xff0c;迁移成本比较高&#x…

MongoDB数据模型和WiredTiger读写模型

MongoDB数据模型 思考&#xff1a;MongoDB为什么会使用BSON&#xff1f; BSON协议与数据类型 JSON JSON是当今非常通用的一种跨语言Web数据交互格式&#xff0c;属于ECMAScript标准规范的一个子集。JSON&#xff08;JavaScript Object Notation, JS对象简谱&#xff09;即J…

调试OpenHarmony应用/服务

调试流程 DevEco Studio提供了丰富的OpenHarmony应用/服务调试能力&#xff0c;帮助开发者更方便、高效的调试应用/服务。 OpenHarmony应用/服务调试支持使用真机设备调试。使用真机设备进行调试前&#xff0c;需要对HAP进行签名后进行调试。详细的调试流程如下图所示&#x…

node.js与express.js创建项目以及连接数据库

搭建项目 一、技术准备 node版本&#xff1a;16.16.0 二、安装node成功后&#xff0c;安装express,命令如下&#xff1a; npm install -g express 或者&#xff1a; npm install --locationglobal express 再安装express的命令工具&#xff1a; npm install --location…

ASP.NET Core 过滤器 使用依赖项注入

过滤器是 ASP.NET Core 中的特殊组件&#xff0c;允许我们在请求管道的特定阶段控制请求的执行。这些过滤器在中间件执行后以及 MVC 中间件匹配路由并调用特定操作时发挥作用。 简而言之&#xff0c;过滤器提供了一种在操作级别自定义应用程序行为的方法。它们就像检查点&#…

JSP仓储管理系统myeclipse定制开发SQLServer数据库网页模式java编程jdbc

一、源码特点 JSP仓储管理系统系统是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库 &#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为SQLServer2008&#x…

Java关于Excel文件的导入导出

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

uniapp多格式文件选择(APP,H5)

uniapp多格式文件选择&#xff08;APP&#xff0c;H5&#xff09; 背景实现代码实现运行结果注意事项 尾巴 背景 从手机选择文件进行上传是移动端很常见的需求&#xff0c;在原生开发时由于平台专一性很容易实现。但是用uniapp开发官方提供的API在APP平台只能选择图片和视频&a…

C语言如何理解 c=a,b;?

一、问题 对于表达式 ca,b;和 d(a,b);该如何进⾏理解&#xff1f;它们的值都是怎样的&#xff1f; 二、解答 在C语⾔中&#xff0c;逗号有两个作⽤&#xff0c;⼀是⽤来分隔函数参数&#xff0c;⼆是作为逗号运算符。本题主要考虑的是逗号运算符&#xff0c;根据逗号运算符的规…

第七篇:node中间件详解

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 引言&#xff1a; &#…