本文是与《C++编程基础及应用》(暂定名)第12章 - 编译及构建配套的操作指南,用于演示在Windows命令行环境下使用mingw编译器手工编译并运行程序的过程。
本文引用自作者编写的下述图书; 本文允许以个人学习、教学等目的引用、讲授或转载,但需要注明原作者"海洋饼干叔
叔";本文不允许以纸质及电子出版为目的进行抄摘或改编。
1.《Python编程基础及应用》,陈波,刘慧君,高等教育出版社。免费授课视频 Python编程基础及应用
2.《Python编程基础及应用实验教程》, 陈波,熊心志,张全和,刘慧君,赵恒军,高等教育出版社Python编程基础及应用实验教程
3. 《简明C及C++语言教程》,陈波,待出版书稿。免费授课视频
在Windows菜单中找到命令提示符(通过输入cmd进行查找),然后点击进入。

在命令提示符中执行命令 gcc -v, 期望如果如下图所示。
如果系统报告“未知的程序”’gcc’ 不是内部或外部命令,也不是可运行的程序或批处理文件“,则说明mingw编译环境尚未得到正确的安装及配置。请按照下述链接中的第一部分进行安装及配置。
http://codelearn.club/2022/09/vsccpp/
在D:\Demo目录里准备如下的三个源代码文件,如果读者的计算机上没有D盘,那就使用C:\Demo目录。
其中,compute.h内容如下:
#ifndef _COMPUTE_H
#define _COMPUTE_H
#define PI 3.1415926 //comment
#define SQUARE(x) x*x
float circleArea(const float r);
#endif
文件compute.c内容如下:
#include "compute.h"
#include "compute.h"
float circleArea(const float r){
float t = PI * SQUARE(r); //comment
return t;
}
文件area.c内容如下:
#include
#include "compute.h"
int main(){
float r = 4.1f;
float a = circleArea(r); //comment
printf("Area of the circle = %f.\n",a);
}
如下图所示,在Windows命令提示符(终端)中依次执行如表1所列的命令,完成上述3个源代码文件的编译,并成功执行了名为area.exe的可执行文件。

表1 在终端里使用gcc编译示例程序并运行
| 命令 | d: |
|---|---|
| 说明 | 切换当前盘符为D盘,如果读者使用的是C:\Demo目录,则不要执行该命令。 |
| 命令 | cd \Demo |
| 说明 | 将当前目录切换为当前盘符下的\Demo目录,示例的3个源代码文件在该目录里。cd是操作系统终端命令,意为改变目录(change directory)。 |
| 命令 | dir |
| 说明 | 终端命令,显示当前目录下的所有文件及子目录。执行结果显示当前目录下有area.c、compute.h及compute.c三个文件。 |
| 命令 | gcc area.c compute.c –o area |
| 说明 | 使用gcc编译器编译area.c及compute.c两个C语言程序文件,生成名为area的可执行目标文件。请注意,头文件compute.h不被视为一个单独的编译单元,所以未在命令中列出。上述命令行中的-o选项意为指定输出文件的名称。该文件执行完成后,再次执行dir,可见当前目录下多了一个名为area.exe的文件,其扩展名exe说明该文件是一个可执行文件(executable file)。 |
| 命令 | area.exe |
| 说明 | 载入并执行当前目录下名为area.exe的可执行目标文件。在执行该命令后,操作系统会将该程序载入内存,然后将执行点转移至该程序的起始处。随后的执行结果可见,area成功计算并打印了半径为4.1的圆的面积。 |
上述示例程序的编译/构建过程可用下图表示:
执行命令
gcc -E compute.c -o compute.i
或者
cpp compute.c compute.i
都可以对源代码文件compute.c进行预处理,对应的输出文件为compute.i。如下图所示:

结果文件compute.i系文本文件,可以使用任意文字编辑软件,比如记事本, 打开。当然,也可以使用Visual Studio Code或者Qt Creator等IDE环境来查看。
在作者的计算机上,compute.i的内容如下:
# 0 "compute.c"
# 0 ""
# 0 ""
# 1 "compute.c"
# 1 "compute.h" 1
float circleArea(const float r);
# 2 "compute.c" 2
float circleArea(const float r){
float t = 3.1415926 * r*r;
return t;
}
编译预处理的具体工作原理请参阅教材第12章。
使用下述命令可以将compute.i进行编译,得到包含汇编语言指令的结果文件compute.s。

同理,compute.s也是文本文件,可用记事本,Visual Studio Code,Qt Creator等工具打开查看。在作者的计算机上,compute.s的内容如下,其包含的是x86的汇编语言指令序列。
.file "compute.c"
.text
.globl circleArea
.def circleArea; .scl 2; .type 32; .endef
.seh_proc circleArea
circleArea:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $16, %rsp
.seh_stackalloc 16
.seh_endprologue
movss %xmm0, 16(%rbp)
pxor %xmm1, %xmm1
cvtss2sd 16(%rbp), %xmm1
movsd .LC0(%rip), %xmm0
mulsd %xmm0, %xmm1
pxor %xmm0, %xmm0
cvtss2sd 16(%rbp), %xmm0
mulsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -4(%rbp)
movss -4(%rbp), %xmm0
addq $16, %rsp
popq %rbp
ret
.seh_endproc
.section .rdata,"dr"
.align 8
.LC0:
.long 1293080650
.long 1074340347
.ident "GCC: (GNU) 12.2.0"
在Windows命令行中执行下述命令之一,可以将compute.s汇编成可重定位目标文件(relocatable object file)compute.o,其为包含机器语言指定的二进制文件。
as compute.s -o compute.o
gcc -c compute.s -o compute.o

结果文件compute.o是二进制文件,直接查看其内容只会得到一堆0和1。在Windows命令行里,可以通过下述命令对其进行反汇编,查看其中的汇编语言指令:

对于编译单元compute.c,经过预处理-编译-汇编之后我们得到可重定位目标文件compute.o。
我们对编译单元area.c进行类似处理,得到可重定位目录文件area.o。

这样,我们就有了两个可重定位目标文件,分别是area.o及compute.o,其中,area.o包含了对compute.o内部的函数的调用。
通过下述命令,我们将area.o及compute.o链接为一个整体,得到可执行文件area.exe,然后再次执行area.exe。

为了帮助更多的年轻朋友们学好编程,作者在B站上开了两门免费的网课,一门零基础讲Python,一门零基础C和C++一起学,拿走不谢!
如果你觉得纸质书看起来更顺手,目前Python有两本,C和C++在出版过程中。