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语言希望有所帮助。前人栽树,后人乘凉~