【C语言】拆解C语言的编译过程

前言

学习C语言的过程中,涉及到各种各样的关键词,在我们点击编译的时候,都会做什么呢?让我们来拆解一下

C语言的编译过程

C语言的编译过程包括预处理、编译、汇编和链接四个主要步骤。每个步骤都有其特定的任务和输出文件类型,通过这些步骤,源代码被逐步转换为可执行的机器码。

预处理

预处理器处理源代码中的预处理指令:

  • 预处理器处理源代码文件中的预处理指令,如#include#define等。
  • #include指令会将指定的头文件内容插入到源文件中。
  • #define指令会进行宏替换。
  • 处理所有条件编译指令(#ifdef#ifndef#endif等)。
  • 预处理后的代码通常会生成一个扩展名通常为.i的文件。
  • 删除所有注释
  • 添加行号和文件名标识,便于在调试和出错时给出具体代码位置

编译

  • 编译器将预处理后的代码转换为汇编代码。
  • 这个阶段会进行语法分析、语义分析、优化等操作。
  • 确定变量的类型,作用域及储存位置。
  • 生成的汇编代码通常保存在一个扩展名为.s的文件中。

汇编

  • 汇编器将汇编代码转换为机器码,即目标代码。
  • 确定局部变量的内存。
  • 生成的目标代码通常保存在一个扩展名为.o.obj的文件中。

链接

  • 链接器将多个目标文件和库文件链接在一起,生成最终的可执行的二进制文件。
  • 链接过程中,链接器会解决符号引用,确保所有函数和变量都能正确调用。
  • 生成的可执行文件在Windows上通常扩展名为.exe,在Unix/Linux系统上没有特定的扩展名。

举例

假设有一个C语言源文件main.c,其内容如下:

cs 复制代码
#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}
1. 预处理

使用gcc编译器的预处理命令:

cs 复制代码
gcc -E main.c -o main.i

生成的main.i文件内容可能如下:

cs 复制代码
# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"

# 1 "/usr/include/stdio.h" 1 3 4
...
# 2 "main.c" 2

int main() {
    printf("Hello, World!\n");
    return 0;
}
2. 编译

使用gcc编译器的编译命令:

cs 复制代码
gcc -S main.i -o main.s

生成的main.s文件内容可能如下:

cs 复制代码
	.file	"main.c"
	.section	.rodata
.LC0:
	.string	"Hello, World!"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	subq	$16, %rsp
	movl	$.LC0, %edi
	call	puts
	movl	$0, %eax
	leave
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0"
	.section	.note.GNU-stack,"",@progbits

使用gcc编译器的汇编命令:

3. 汇编

使用gcc编译器的汇编命令:

cs 复制代码
gcc -c main.s -o main.o

生成的main.o文件是二进制格式的目标文件。

4. 链接

使用gcc编译器的链接命令:

cs 复制代码
gcc main.o -o main

生成的main文件是最终的可执行二进制文件。

总结

C语言的编译过程包括预处理、编译、汇编和链接四个主要步骤。每个步骤都有其特定的任务和输出文件类型,通过这些步骤,源代码被逐步转换为可执行的机器码。

相关推荐
Esaka_Forever11 小时前
Python 与 JS (V8) 垃圾回收核心区别 + 底层根源分析
开发语言·javascript·jvm
十月的皮皮11 小时前
C语言学习学习笔记20260704-中缀表达式求值(双栈法)
c语言·笔记·学习
pp起床11 小时前
黑马点评 - 短信验证码登录实现
java·开发语言·tomcat
芒鸽11 小时前
在仓颉语言里造一个没有反射的服务端框架
开发语言·华为·harmonyos
CodeStats11 小时前
《源纹天书》第121-125章:源匠归来——全栈重构与归元圣域的2.0时代
java·开发语言·源纹天书
binbin_5211 小时前
UIAbility 与 WindowStage:窗口创建、加载、销毁的完整链路
开发语言·javascript·深度学习·华为·harmonyos
AI人工智能+电脑小能手11 小时前
【大白话说Java面试题 第154题】【06_Spring篇】第14题:Spring 支持的 Bean 作用域
java·开发语言·spring·面试
wuminyu11 小时前
markword在高并发场景下变化剖析
java·linux·c语言·jvm·c++
星夜夏空9911 小时前
C++学习(1) ——C与C++
c语言·c++·学习
旖-旎12 小时前
QT界面优化(6)
开发语言·c++·qt