Gcc概述:把高级语言转化为机器语言的工具集
gcc -v //查询gcc版本 gcc -o 输出文件名 输入文件名(源文件) //编译 ./输出文件名 gcc -v -o build text.c //详细显示gcc编译时的过程
C语言编译过程介绍
1.预处理阶段,GCC编译器执行宏替换、头文件包含、条件编译等操作。这个阶段的目的是处理源代码中的预处理指令,生成一个经过预处理的源代码文件,通常以.i为文件扩展名。预处理后的代码包含了所有必要的头文件内容和宏定义的展开结果,但不包含任何编译指令或语法分析信息(不对代码进行检查)。
2.编译阶段是将预处理后的源代码转换为汇编语言代码的过程。在这个阶段,编译器进行词法分析、语法分析、语义分析和优化。编译器检查代码的语法错误,分析变量和函数的使用情况,并执行代码优化以提高程序的运行效率和减少内存占用。生成的汇编语言代码对应于目标平台的机器指令集,但仍以人类可读的形式存在。
3.汇编阶段是将汇编语言代码转换为机器语言的二进制代码的过程。汇编器处理汇编语言指令,将它们转换为机器代码,并生成目标文件,通常具有.o或.obj的文件扩展名。这个阶段涉及符号解析和重定位等操作,确保生成的机器代码可以在目标硬件上正确执行。
4.链接阶段是将一个或多个目标文件与其依赖的库合并,生成最终的可执行文件。链接器处理符号解析、地址和偏移量分配等任务,确保所有外部引用都被正确解决。在这个阶段,动态链接库(DLLs)或静态链接库(static libs)中的函数和数据被整合到最终的可执行文件中。链接完成后,生成的文件可以在操作系统上运行,不需要额外的库文件。
【问题】 define include 是关键字吗? 不是,define include在预处理阶段就已经处理完
预处理 c文件 -> .i文件 命令:gcc -E -o a.i text.c 编译 c文件 -> .s文件 命令:gcc -S -o a.s text.c(gcc的编译过程会包括预处理) 汇编 .s文件 -> .o文件 命令:gcc -c -o a.o a.s 链接 命令:gcc -o
C语言编译常见错误举例
预处理错误
【问题】 not found:头文件包含出错,如自定义的头文件和需要编译的文件不在同一目录下 【解决方法】 1.#include "abc.h" -> #include "./inc/abc.h" 2.增加选项:gcc -I查找头文件的目录 gcc -I./inc -o build text.c
编译错误
【问题】 ; {} 缺少
链接错误
【问题】 collect2:链接器报错 原材料少了:undefined reference to 'name' 原材料多了:multiple definition of 'name',多次实现了标签,只保留一个
预处理的使用
#include 包含头文件 在当前的位置上,对这个文件内容进行展开,再通过gcc把这个文件进行编译
#define 宏 -> 替换 不进行语法检查的展开 #define 宏名 宏体 ->安全->加括号 #define ABC (5+3) 宏函数 #define ABC(x) (5+(x)) ->5+x对x进行替换
#ifdef #else #endif 条件预处理 在程序开发的过程中,通常会有两个版本 调试版本debug 发行版本release 需求:在调试时输出某些调试的信息,但在发行版本时将这些调试信息关闭 int main() { #ifdef ABC printf("------------");//调试信息,发行版本中不需要打印 #endif printf("hello world!");//普通输出信息 return 0; } 当程序预先已经定义了ABC时,#ifdef ABC 这句话为真,将执行调试信息的打印输出并输出hello world! 反之,则不打印输出调试信息,只输出hello world! 利用-D选项在输入编译命令时,提前定义ABC,而不用修改源代码 gcc -DABC 等价于在源文件添加 #define ABC 命令:gcc -DABC -o build text.c
预定义宏 系统定义的宏 前后都是两个下划线 __FUNCTION__ 函数名 __LINE__ 行号 __FILE__ 文件 在调试开发的过程中,利用预定义宏,可以迅速找到报错语句的位置 printf("the %s,%s,%d\n",__FUNCTION__,__FILE__,__LINE__);
宏展开下的# , ## 在宏体中实现 # 字符串化 #define ABC(x) #x ## 连接字符 #define ABC(x) day##x ->dayx 代码: #include <stdio.h> #define ABC(x) #x #define DAY(x) myday##x int main() { int myday1=10; int myday2=20; printf("ABC(ab\n)"); printf("the day is %d and %d\n",DAY(1),DAY(2)); return 0; } 程序输出: "ab" "the day is 10 and 20"
欢迎批评指正。