C语言编译流程

简介: 1编译流程图示2编译各阶段命令2-1预处理阶段2-2 编译阶段2-3 汇编阶段2-4 链接阶段3例子1、编译流程图示我们在Linux环境下编译单个C文件时,最简单的方法是输入一条命令gcc hello.c就可以生成默认的可执行文件a.out,展开该命令可以看到实际流程如下。

1、编译流程图示

我们在Linux环境下编译单个C文件时,最简单的方法是输入一条命令gcc hello.c就可以生成默认的可执行文件a.out,展开该命令可以看到实际流程如下。
(编译命令参数请看 gcc使用手册

这里写图片描述

预处理阶段 -> 编译阶段 -> 汇编阶段 -> 链接阶段

2、编译各阶段命令

  • 预处理阶段
  • 编译阶段
  • 汇编阶段
  • 链接阶段

2-1预处理阶段

把.c文件预处理命令替换为对应的头文件内容,并合并成.i文件中。

gcc -E -o hello.i hello.c

预处理阶段主要处理下面四件事:

  • 将头文件内容包含进.c源文件中;
  • 删除注释;
  • 宏替换;
  • 条件编译;

2-2 编译阶段

把源文件编译成汇编语言,并生成.s文件。

gcc -S -o hello.s hello.i
// or
gcc -S -o hello.s hello.c

2-3 汇编阶段

把源文件汇编成机器语言,并生成.o目标文件。

gcc -o hello.o -c hello.s
// or
gcc -o hello.o -c hello.i
gcc -o hello.o -c hello.c

2-4 链接阶段

把源文件链接成可执行文件(Linux下的文件名后缀是随便可取的,只是文件里的内容格式不变而已)。

gcc -o hello hello.o
// or
gcc -o hello hello.s
gcc -o hello hello.i
gcc -o hello hello.c
gcc hello.c

3、例子

wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ls
mymathfun.c  mymath.h  mymath_test.c
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ cat -n mymath_test.c 
     1  #include <stdio.h>
     2  #include "mymath.h"
     3  
     4  int main()
     5  {
     6      printf("My Pi: %lf\n", my_pi());
     7      return 0;
     8  }
     9  
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c 
/tmp/ccRCzDfw.o:在函数‘main’中:
mymath_test.c:(.text+0x5):对‘my_pi’未定义的引用
collect2: error: ld returned 1 exit status
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c mymathfun.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ./a.out 
My Pi: 3.141593
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ vim mymath_test.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ cat -n mymath_test.c 
     1  #include <stdio.h>
     2  #include "mymath.h"
     3  #include "mymathfun.c"
     4  
     5  int main()
     6  {
     7      printf("My Pi: %lf\n", my_pi());
     8      return 0;
     9  }
    10  
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c 
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ ./a.out 
My Pi: 3.141593
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ gcc mymath_test.c mymathfun.c 
/tmp/ccMnE10S.o:在函数‘my_pi’中:
mymathfun.c:(.text+0x0): `my_pi'被多次定义
/tmp/cc89I2rk.o:mymath_test.c:(.text+0x0):第一次在此定义
collect2: error: ld returned 1 exit status
wu_being@UbuntuKylin1704:~/Code/C/test_cpp$ 

Wu_Being博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
《C语言编译流程》: http://blog.csdn.net/u014134180/article/details/78329908

Wu_Being 吴兵博客接受赞助费二维码

如果你看完这篇博文,觉得对你有帮助,并且愿意付赞助费,那么我会更有动力写下去。

目录
相关文章
|
2月前
|
存储 自然语言处理 编译器
【C语言】编译与链接:深入理解程序构建过程
【C语言】编译与链接:深入理解程序构建过程
|
2月前
|
自然语言处理 编译器 Linux
【C语言篇】编译和链接以及预处理介绍(上篇)1
【C语言篇】编译和链接以及预处理介绍(上篇)
42 1
|
4月前
|
NoSQL 编译器 程序员
【C语言】揭秘GCC:从平凡到卓越的编译艺术,一场代码与效率的激情碰撞,探索那些不为人知的秘密武器,让你的程序瞬间提速百倍!
【8月更文挑战第20天】GCC,GNU Compiler Collection,是GNU项目中的开源编译器集合,支持C、C++等多种语言。作为C语言程序员的重要工具,GCC具备跨平台性、高度可配置性及丰富的优化选项等特点。通过简单示例,如编译“Hello, GCC!”程序 (`gcc -o hello hello.c`),展示了GCC的基础用法及不同优化级别(`-O0`, `-O1`, `-O3`)对性能的影响。GCC还支持生成调试信息(`-g`),便于使用GDB等工具进行调试。尽管有如Microsoft Visual C++、Clang等竞品,GCC仍因其灵活性和强大的功能被广泛采用。
138 1
|
2月前
|
存储 自然语言处理 编译器
C语言编译和链接
C语言编译和链接
C语言编译和链接
|
2月前
|
编译器 Linux C语言
【C语言篇】编译和链接以及预处理介绍(下篇)
【C语言篇】编译和链接以及预处理介绍(下篇)
33 1
【C语言篇】编译和链接以及预处理介绍(下篇)
|
2月前
|
自然语言处理 编译器 Linux
C语言中抽象的编译和链接原理
C语言中抽象的编译和链接原理
22 1
|
2月前
|
存储 C语言
【C语言篇】编译和链接以及预处理介绍(上篇)2
【C语言篇】编译和链接以及预处理介绍(上篇)
38 0
|
3月前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
3月前
|
C语言
C语言 网络编程(七)UDP通信创建流程
本文档详细介绍了使用 UDP 协议进行通信的过程,包括创建套接字、发送与接收消息等关键步骤。首先,通过 `socket()` 函数创建套接字,并设置相应的参数。接着,使用 `sendto()` 函数向指定地址发送数据。为了绑定地址,需要调用 `bind()` 函数。接收端则通过 `recvfrom()` 函数接收数据并获取发送方的地址信息。文档还提供了完整的代码示例,展示了如何实现 UDP 的发送端和服务端功能。
|
3月前
|
网络协议 C语言
C语言 网络编程(十)TCP通信创建流程---客户端
在TCP通信中,客户端需通过一系列步骤与服务器建立连接并进行数据传输。首先使用 `socket()` 函数创建一个流式套接字,然后通过 `connect()` 函数连接服务器。连接成功后,可以使用 `send()` 和 `recv()` 函数进行数据发送和接收。最后展示了一个完整的客户端示例代码,实现了与服务器的通信过程。