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

2024-02-26 1154阅读

温馨提示:这篇文章已超过388天没有更新,请注意相关的内容是否还可用!

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

      编译前:

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

      编译后:

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

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

      方法一:

      gcc + -o 选项 + 文件名1 +文件名2

      方法二:

      gcc +文件名2+ -o 选项 + 文件名1

      解释:

      文件名1:生成的可执行文件的文件名 (示例: hello.exe)

      文件名2: 带编译的源文件 (示例: hello.c)

      指定生成的可执行文件的文件名:

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

      编译c++代码:

      首先如果没有安装g++命令,可以先安装一下。

      安装g++命令:

      yum install gcc-c++
      

      编译指令:

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

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

      示例:

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

      编译原理:

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

      四个阶段

      Linux下如何编译C/C++代码?从.c到.exe经历了什么?(图片来源于上推荐文章,图片稍作修改了)

      4.1 “预处理”阶段:

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

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

      指令: 以test.c为例。

      gcc -E test.c -o test.i
      

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

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

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

      🔑vim使用小技巧:

      可以在底行模式下,可以使用vs + 文件名 的方式,同时查看打开两个文件。

      文件之间的切换: ctrl+w+w

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

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

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

      在学习C语言阶段,存在一个疑问:为什么“宏”不会做语法检查?

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

      答案:

      宏是在预处理阶段被直接替换的,而语法检查是在编译(下面讲解的)阶段进行的。在预处理阶段,宏已经被展开成了代码片段,而编译器只能看到这些展开后的代码片段,无法像对待普通代码一样进行语法检查。此外,宏可以使用一些编译器无法理解的语法,这也导致了宏无法进行语法检查。

      注意:

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

      补充小知识:

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

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

      得到了下面的效果:

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

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

      示例:

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

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

      4.2 “编译”阶段

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

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

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

      为什么会报错呢?

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

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

      那为什么预处理就直接通过了呢?

      因为“语法分析”和“词法分析”是在编译阶段进行的,所以在编译阶段就直接报错了。

      原“演示”代码

      #include 
      #include  
      #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 
      #include  
      #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. 符号汇总

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

      下图示例:

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

      4.3 “汇编”阶段

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

      啊,好累,这么麻烦,咋还有!

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

      下一个选项登场:

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

      注意这里是小写的c哦。

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

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

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

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

      xxd -b test.o>mycode
      

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

      打开后:

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

      4.4 “链接”阶段

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

      总结:

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

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

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]