gcc/g++编译器

本文详细介绍了Linux环境下gcc/g++编译器的工作原理,包括编译过程的四个阶段:预处理、编译、汇编和链接,并讨论了静态库和动态库的区别及其在Linux中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux中,gcc/g++ 编译器。四个编译过程——预处理, 编译,汇编,链接。


一、Linux编译器gcc和g++

(1)gcc/g++介绍
  • gcc是编译c代码的编译器, g++是编译c++代码的编译器。
  • c++代码的后缀有三种:①“.cpp”。②“.cc”。③“.cxx”。
(2)安装gcc-c++
sudo yum install -y gcc-c++
gcc --version 		// 查看gcc版本
g++ --version 		// 查看g++版本
(3)gcc使用
  1. gcc最简单的使用。 gcc默认生成一个 **“a.out”**的可执行文件。

    gcc test.c
    
  2. 使用**“-o”**选项可以指定生成的可执行文件名称。比如:“test.exe”。

    gcc -o test.exe test.c
    gcc test.c -o test.exe 
    
    • 上述两种写法完全一样,没有区别。
  3. 使用指定的c标准进行编译。比如: **“-std=c99”**使用c99标准

    gcc test.c -std=c99			// 使用c99标准
    g++ test.cc -std=c++11		// 使用c++11标准
    

二、C/C++代码编译的过程

(1)预处理阶段(进行宏替换等)
  • 在这个阶段,编译器gcc/g++主要对c源代码进行宏替换去注释头文件展开,和条件编译等,预处理后生成一个**“*.i”**后缀的c代码。

    1. 宏替换:例如:#define M 100,在预处理阶段,编译器将宏M 替换成100

    2. 去注释:在预处理阶段,编译器将所有的注释去除

    3. 头文件展开:将#include<stdio.h>包含的头文件从c标准库中拷贝到c源代码里。

    4. 条件编译:(可用于维护不同版本的软件,比如社区版,个人版,企业版)

      #ifdef V1
      // ...
      #elif V2
      //...
      #else
      //...
      #endif
      
      • Linux中可以在命令行添加宏定义,“-D” 表示定义宏,紧接着的就是宏的名字和值。

        gcc -D V1=1 test.c
        
  • 实例:

    gcc -E hello.c -o hello.i
    
    1. 其中 “-E”表示编译器从现在开始进行程序的翻译,预处理完成后,就停下来。
    2. “-o”表示指定生成的目标文件名称。
    3. ".i"文件是一个经过处理后的C代码初始文件。
(2)编译阶段(生成汇编代码)
  • 编译器gcc/g++会检查代码的规范性,检查是否有语法错误,确定代码实际要做的工作,确定动态链接库的地址等,检查无误后,gcc将c代码翻译成汇编代码。

  • 实例:

    gcc -S hello.i -o hello.s
    
    1. “-S” 表示编译器从现在开始进行程序的编译,编译完成后,就停下来,并生成汇编代码。
    2. “.s" 文件里面是汇编代码。
(3)汇编阶段(生成机器可识别的二进制代码)
  • 编译器gcc/g++将编译阶段生成的”.s“文件转成机器可识别的二进制目标代码(”.o“文件)。

  • 实例:

    gcc -c hello.s -o hello.o
    
    1. ”-c" , 编译器将.s文件转换成.o文件
    2. hello.o 是一个二进制文件,但是不能直接运行,因为还需要动态库里面的一些方法等。
(4)链接阶段(生成可执行文件或库文件)
  • 在成功编译后就进入到链接阶段。gcc/g++让我们的程序和c标准库结合起来的过程。

  •   gcc hello.o -o hello.exe 
    
    1. 将hello.o 与动态库链接起来,生成可执行的二进制程序。
(5)总结
  • 预处理: 进行宏替换,去注释,头文件展开,条件编译等,生成后缀为**“.i”**的c源代码。
  • 编译: 将预处理阶段生成的“.i”c源代码,转换成“.s”的汇编代码。
  • 汇编: 将编译阶段生成的“.s”文件,转换成".o"的二进制代码。
  • 链接: 将汇编阶段生成的“.o”文件, 与库文件结合起来,生成可执行程序。

三、静/动态库

(1)静态库
  • 静态库是指编译链接时,把库文件的代码全部加入到可执行程序中,因此生成的文件会比较大,但在运行时就不需要库文件了,有较好的可移植性跨平台性。一般静态库后缀名为“.a”。

  • Linux中一般没有c/c++的静态库,需要我们自行下载:

    // c静态库
    sudo yum install -y glibc-static
    // c++静态库
    sudo yum install -y libstdc++-static
    
  • 静态库在Linux中的位置:

    /usr/lib64/libc.a
    
(2)动态库
  • 动态库与之相反,不需要将库文件拷贝到可执行程序中,而是在程序执行时由运行时的链接文件来加载库文件, 这样可以节省系统的开销,但是,一旦动态库丢失,所有的动态链接这个库的程序都无法执行。一般动态库后缀名为“.so”。

  • 动态库在Linux中的位置:

    /usr/lib64/libc.so.6
    //==== libc.so.6 是 libc-2.17.so 的软链接,相当于快捷键 ====
    // libc-2.17.so 与之在同一位置
    /usr/lib64/libc-2.17.so
    

优缺点:

  • 动态库和动态链接:不能丢失,但节省空间。

  • 静态库和静态链接: 一旦形成和库无关,但拷贝会浪费空间。

注意:

  • 在Linux 中,c/c++动态库是默认提供的, 而c/c++静态库是没有安装的。

  • gcc 默认生成的可执行程序, 默认采用动态链接

(3)gcc默认生成的二进制程序,是动态链接的,使用file 指令可验证:
file my.exe
ldd my.exe
  • file 指令:查看文件的具体类型。
  • ldd指令:查看可执行程序所依赖的库。
(4)Windows 中的库
  • 动态库后缀:“.dll”
  • 静态库后缀:“.lib”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值