gcc的编译C语言的过程

gcc的简介

        GCC(GNU Compiler Collection)是由GNU项目开发和维护的一套开源编程语言编译器集合。它支持多种编程语言,包括但不限于C、C++、Objective-C、Fortran、Ada等。GCC被广泛应用于编译和优化各种程序,是许多开发者和组织的首选工具之一。gcc默认编译C语言。  

gcc编译C语言过程

过程简介:预处理、编译、汇编、链接四个过程,由.c文件形成中间文件:.i、.s、.o文件,最终形成可执行文件。

预处理:将.c中的头文件展开、宏展开、条件编译、注释删除,生成的文件是.i文件,注意预处理过程不会对文件代码做任何语法检查。

gcc -E hello.c -o hello.i \\-E选项指定gcc只做预处理过程

编译:将预处理后的.i文件生成.s汇编文件,注意编译过程会对代码进行语法检查。

gcc -S hello.i -o hello.s    //-S选项指定gcc只做编译过程

汇编:将编译产生的汇编文件处理生成.o目标文件,也就是汇编语言转换为二进制语言

gcc -c hello.s -o hello.o    //-c选项指定gcc将汇编文件转换为目标文件

链接:将.o文件链接成目标文件,多个.c源文件经过四个步骤最终形成了我们想要的目标文件,也就是最终的可执行文件。

gcc hello.o -o hello    \\通过gcc将多个*.o链接成一个可执行文件

案例

代码目录结构:

.
├── hello.i        //cat main.i myfunc.i > hello.i,是gcc生成的.i文件
├── hello.s        //cat main.s myfunc.s > hello.s,是gcc生成的.s文件
├── main.c         //源文件
├── main.i        //gcc -E main.c -o main.i
├── main.o        //gcc -c main.s -o main.o
├── main.s        //gcc -S main.i -o main.s
├── my_execfile        //gcc main.o myfunc.o -o my_execfile 最终的目标文件
├── myfunc.c         //源文件
├── myfunc.h         //头文件
├── myfunc.i        //gcc -E myfunc.c -o myfunc.i
├── myfunc.o        //gcc -c myfunc.s -o myfunc.o
└── myfunc.s        //gcc -S myfunc.i -o myfunc.s

0 directories, 12 files

maic.c

#include <stdio.h>
#include "myfunc.h"  // 包含自定义头文件

// 宏定义
#define MAX(x, y) ((x) > (y) ? (x) : (y))
#define A 10
int main() {
    int b = 20;
    int maxValue;

    // 基于宏的条件编译
    #ifdef DEBUG
        printf("调试模式已启用。\n");
    #else
        printf("调试模式已禁用。\n");
    #endif

    // 使用MAX宏
    maxValue = MAX(A, b);
    printf("%d和%d之间的最大值是:%d\n", A, b, maxValue);

    // 调用在myfunc.h中定义的函数
    int factorialResult = factorial(5);
    printf("5的阶乘是:%d\n", factorialResult);

    return 0;
}

myfunc.h

#ifndef MYFUNC_H  // 头文件包含保护,以防止多重包含
#define MYFUNC_H

// 阶乘函数的函数原型
int factorial(int n);

#endif  // 头文件包含保护结束

myfunc.c

#include "myfunc.h"

// 阶乘函数的定义
int factorial(int n) {
    if (n <= 1)
        return 1;
    else
        return n * factorial(n - 1);
}

1、预处理:通过gcc工具链指定-E选项对maic.c、myfunc.c文件处理,即只进行预处理过程,形成hello.i文件,该过程会对宏展开,宏条件编译选择,头文件展开,注释全部删除。可通过操作验证。

hello.i部分内容

2、编译:通过gcc工具链指定-S选项对maic.i、myfunc.i文件处理,即只进行编译过程,形成main.s、myfunc.s文件,该过程会对*.i文件进行语法检查,确保语法正确并生成*.s汇编文件。可通过操作验证。补充:汇编语言是最接近二进制语言的低级编程语言,所有的高级编程语言要中转汇编语言。

hello.s部分内容

 3、汇编:通过gcc工具链指定-c选项对maic.s、myfunc.s文件处理,即只进行汇编过程,形成main.o、myfunc.o文件。可通过操作验证。补充:*.o是目标文件,也就是可执行文件,该文件一般不可读(乱码),是机器设备能识别的二进制语言文件。

4、链接:通过gcc工具链对maic.o、myfunc.o文件进行链接,形成my_execfile文件,即最终的可执行文件。可通过操作验证。

执行:./my_execfile

预处理过程案例补充

 预处理过程会对宏条件编译根据条件进行一次选择处理

上面的预处理步骤变化:加宏-DDEBUG,条件发生变化

gcc -E main.c -o main.i -DDEBUG    //加宏参数对宏条件选择预处理

main.i 部分内容 (上面的预处理过程输出结果由禁用条件被替换成启用条件)

 

小结

以上的步骤其实都可以被优化,我们编译文件只需要执行gcc -o my_execfile hello.c即可生成最终的可执行文件my_execfile

然而,这条语句依然可以进一步的优化,通过makefile文件处理,执行make,也可以形成我们最终想要的可执行文件,不管是哪种优化,都离不开千锤百炼的基础和经验,以上内容对于了解c语言希望有所帮助。前人栽树,后人乘凉~ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值