gcc和g++
1. 概览:什么是gcc和g++?为什么要用它们?
- gcc:用来编译C语言(后缀名通常是
.c
) - g++:用来编译C++语言(后缀名可以是
.cpp
、.cc
、.cxx
)
它们的作用就是把你的源代码(写的程序)变成可以运行的“机器指令”。Linux系统没有像Windows那样的“点后缀名就是C或C++”的规则,但文件后缀名帮助我们识别。
2. 编译过程:从源码到可执行文件的每一步
这里我们把编译过程拆开,讲得细一些,用故事的方式帮助理解。
2.1 你写的代码
你写了一个程序,比如叫做hello.c
(用C写的):
#include <stdio.h>int main() {printf("Hello, Linux!\n");return 0;
}
或者C++版本的hello.cpp
:
#include <iostream>int main() {std::cout << "Hello, Linux!" << std::endl;return 0;
}
2.2 编译前:预处理(Preprocessing)
这一步干什么?
就像帮你整理备用材料一样,预处理会处理所有以#
开头的指令,比如宏定义、文件包含、条件编译等。
举个例子:
假设你在代码中写了:
复制代码
#define MESSAGE "Hello"printf("%s\n", MESSAGE);
预处理会把MESSAGE
替换成"Hello"
。
命令:
gcc -E hello.c -o hello.i
-E
:让gcc只做预处理,不继续后面的步骤-o hello.i
:把预处理完的内容存到hello.i
文件里
2.3 编译(Compilation)
做什么?
把预处理后代码,变成“汇编语言”。就像是翻译,把人类可以理解的代码变成“基础的指令”。
用命令:
gcc -S hello.i -o hello.s
-S
:只编译到汇编阶段,不生成目标文件hello.s
:存放最终的汇编代码
**简单理解:**这个阶段检查语法,确保没有错误,然后翻译成assembler(汇编代码)。
2.4 汇编(Assembling)
做什么?
把汇编代码转成“机器语言”——0和1组成的目标文件(.o
文件),这是给“计算机看”的。
命令:
gcc -c hello.s -o hello.o
-c
:只做汇编,不后续链接hello.o
:输出二进制的目标文件
一般情况下,直接用gcc
就会自带这个过程,但这是帮你理解每一环。
2.5 链接(Linking)
做什么?
把所有的目标文件(.o
文件)和需要的库(比如libc
)“粘在一起”,形成最终的可执行程序。
命令:
复制代码
gcc hello.o -o hello
-o hello
:指定最终生成的可执行文件名,比如叫hello
**提示:**不是所有时候都需要手动执行每个步骤,通常你只需一条命令:
复制代码
gcc hello.c -o hello
这会自动帮你完成预处理、编译、汇编、连接全部工作。
3. 函数库(Libraries)是啥?
你写printf()
,它其实不是你自己写的函数,而是来自一个叫“库(library)”的东西。比如libc
库,里面存放了各种标准函数。
- 静态库(
.a
文件):在编译时把库的内容“打包”到你的程序里,体积大,但不用额外库文件就能运行。 - 动态库(
.so
文件):在程序运行时“载入”库,只连接一次,节省空间。
默认情况下,gcc会用动态链接(.so
库)方式,除非你特别要求静态链接。
4. 总结一遍:流程一览
阶段 | 作用 | 常用命令 |
---|---|---|
预处理 | 替换宏定义、文件包含,处理注释 etc. | gcc -E source.c 或 -E |
编译 | 转成汇编代码 | gcc -S source.i |
汇编 | 转成机器码(目标文件.o 文件) | gcc -c source.s |
链接 | 生成可执行文件或库 | gcc -o program source.o |
5. 用一句话总结:
“用gcc/g++,你把写好的代码(C或C++)交给它,它就会帮你经过预处理、编译、汇编、链接,最终让你的程序可以跑起来。”
6. 简单示例:
直接用一条命令把代码编译成“能跑”的程序:
gcc hello.c -o hello
或者在没有写头文件和参数的情况下,直接写:
gcc hello.c
这会默认把生成的可执行文件叫做a.out
。