12. [1] 常用编译命令g++的基本使用

1. 概念介绍
g++ 是 GNU Compiler Collection (GCC) 的一部分,是 GNU 项目发布的 C++ 编译器。它是 Linux 系统上最常用、也是事实上的标准 C++ 编译器。即使你使用 IDE(如 Code::Blocks),其背后调用的很可能就是 g++
命令。
学习直接使用 g++
命令,可以让你摆脱对 IDE 的依赖,更深入地理解编译过程,并且能够在任何只有命令行的环境(如远程服务器、竞赛评测系统)中工作。
命令行接口 (Command-Line Interface, CLI) 或 终端 (Terminal) 是一个基于文本的界面,用户通过输入命令来与计算机交互。
2. 算法步骤 (操作流程)
- 准备源代码 : 使用任意文本编辑器(如 gedit, nano, vim, 或 VS Code)创建一个 C++ 源文件,例如
program.cpp
。 - 打开终端 : 在 Linux 中,通常按
Ctrl + Alt + T
或从应用程序菜单中找到"终端"。 - 导航到文件目录 : 使用
cd
(Change Directory) 命令进入你保存program.cpp
的文件夹。例如,如果文件在桌面的MyCode
文件夹里,命令是cd ~/Desktop/MyCode
。 - 编译代码:
-
- 使用
-o
(output) 标志,可以指定生成的可执行文件名为my_program
。这是最推荐的做法。
- 使用
-
- 这会编译
program.cpp
并生成一个名为a.out
的默认可执行文件。
- 这会编译
-
- 最简单的命令 :
g++ program.cpp
- 指定输出文件名 :
g++ program.cpp -o my_program
- 最简单的命令 :
- 运行程序:
-
- 在终端中输入
./
加上你的可执行文件名:./my_program
./
表示"当前目录",告诉系统在当前文件夹下查找并运行这个程序。
- 在终端中输入
- 查看结果: 程序的输出会直接显示在终端中。
3. 算法可视化SVG图示

4. 核心特性
- 命令行驱动: 所有操作通过命令和参数完成,没有图形界面。
- 高度可配置: 可以通过大量的编译标志(flags)来精确控制编译过程的方方面面。
- 透明化: 编译的每一步都清晰可见,错误和警告信息会直接打印在终端上。
- 脚本化: 可以轻松地将编译命令写入脚本(如 Shell 脚本或 Makefile),实现自动化构建。
5. C++代码基础实现
这个 program.cpp
文件是你将要用 g++
命令编译的对象。
program.cpp
c
#include <iostream>
#include <vector>
int main() {
std::vector<std::string> messages = {"Hello", "from", "the", "command", "line!"};
for (const std::string& msg : messages) {
std::cout << msg << " ";
}
std::cout << std::endl;
return 0;
}
6. 优化策略 (常用编译标志)
在 g++
命令后添加标志可以改变其行为。
-o <filename>
: 指定输出文件的名称。-
g++ main.cpp -o main
-std=<standard>
: 指定 C++ 语言标准。竞赛中常用c++11
,c++14
,c++17
。-
g++ main.cpp -o main -std=c++17
-Wall
: 显示所有(All)常见的警告(Warning)。强烈推荐始终使用,可以帮助发现潜在问题。-
g++ -Wall main.cpp -o main
-O2
: 开启二级优化(Optimization)。这会让编译器尝试优化代码以提高运行速度。在提交竞赛代码时通常会开启此选项。-
g++ -O2 main.cpp -o main
-g
: 加入调试信息。如果你想使用 GDB 调试器来调试程序,必须在编译时加上这个标志。-
g++ -g main.cpp -o main
组合使用 : g++ -std=c++17 -Wall -O2 main.cpp -o main
是一个非常实用和全面的编译命令。
7. 优缺点
优点:
- 通用性: 在任何有 GCC 的系统上(几乎所有 Linux 和 macOS)都可以使用,是后台评测系统的标准。
- 轻量高效: 只需一个终端,不占用额外资源。
- 控制力强: 精确控制编译的每一个细节。
- 利于理解: 迫使你理解从源代码到可执行文件的完整过程。
缺点:
- 学习曲线陡峭: 需要记忆命令和参数,对新手不友好。
- 手动操作 : 对于多文件项目,手动输入编译命令会变得繁琐(通常会用
make
等工具解决)。 - 集成度低: 编辑、编译、调试是分离的步骤,需要使用不同的工具。
8. 应用场景
- 信息学竞赛在线评测 (Online Judge, OJ) : 所有 OJ 系统都是在命令行环境下使用
g++
或类似编译器来编译你的提交代码。 - 远程服务器开发: 当你通过 SSH 连接到一台远程 Linux 服务器时,通常只有命令行界面。
- 自动化构建: 编写脚本来自动编译和测试程序。
- 快速验证 : 对于单个文件的小程序,直接在终端用
g++
编译比打开一个大型 IDE 更快。
9. 扩展
- 编译多个源文件 :
g++ file1.cpp file2.cpp -o program
- 链接库 : 使用
-l
标志来链接外部库,例如链接数学库libm.so
:g++ main.cpp -o main -lm
make
和Makefile
: 当项目文件变多时,手动管理编译命令很困难。make
是一个自动化构建工具,它读取名为Makefile
的配置文件,根据文件的依赖关系和修改时间,智能地决定需要重新编译哪些文件。- **GDB (GNU Debugger)****: 学习使用命令行调试器 GDB,它是
g++ -g
编译出的程序的配套调试工具。
10. 5个课后配套练习及C++代码实现答案
每个练习的答案包含 C++ 代码和用于编译运行的命令。
-
练习 : 编写一个程序,打印你的学校名称。使用
g++
将其编译为名为myschool
的可执行文件并运行。答案 :school.cpp
c#include <iostream> int main() { std::cout << "Peking University" << std::endl; return 0; }
命令:
bashg++ school.cpp -o myschool ./myschool
-
练习 : 编写一个程序,读取两个整数并输出它们的差。使用
-std=c++11
和-Wall
标志进行编译。答案 :diff.cpp
c#include <iostream> int main() { int a, b; std::cin >> a >> b; std::cout << a - b << std::endl; return 0; }
命令:
inig++ -std=c++11 -Wall diff.cpp -o diff ./diff
-
练习 : 编写一个程序,其中包含一个未使用的变量。使用
-Wall
标志编译它,并观察终端输出的警告信息。答案 :warning.cpp
c#include <iostream> int main() { int unused_var = 10; // This will trigger a warning std::cout << "Check the compiler warning." << std::endl; return 0; }
命令与预期输出:
csharpg++ -Wall warning.cpp -o warning # 终端会显示类似这样的警告: # warning.cpp: In function 'int main()': # warning.cpp:4:9: warning: unused variable 'unused_var' [-Wunused-variable] # int unused_var = 10; # ^~~~~~~~~~~~ ./warning
-
练习 : 编写一个计算斐波那契数列第 N 项的程序(使用递归,不考虑效率)。使用
-O2
优化标志编译,并与不使用优化的版本比较(虽然对于小 N 可能看不出时间差异,但这是个好习惯)。答案 :fib.cpp
c#include <iostream> int fibonacci(int n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); } int main() { int n = 10; // Calculate the 10th Fibonacci number std::cout << "Fib(" << n << ") = " << fibonacci(n) << std::endl; return 0; }
命令:
bash# 优化版本 g++ -O2 fib.cpp -o fib_opt ./fib_opt # 非优化版本 g++ fib.cpp -o fib_no_opt ./fib_no_opt
-
练习 : 创建两个文件
main.cpp
和helper.cpp
。helper.cpp
中定义一个函数,main.cpp
中调用它。将这两个文件一起编译成一个名为multi_file_test
的程序。答案 :helper.h
(头文件,可选但推荐)arduino#ifndef HELPER_H #define HELPER_H void print_message(); #endif
helper.cpp
c#include <iostream> #include "helper.h" void print_message() { std::cout << "This message is from helper.cpp!" << std::endl; }
main.cpp
arduino#include "helper.h" int main() { print_message(); return 0; }
命令:
bashg++ main.cpp helper.cpp -o multi_file_test ./multi_file_test
11. 相关网络资源推荐
- GCC and Make - A Tutorial on how to compile, link and build C/C++ applications
- g++ command in Linux with examples (GeeksforGeeks)
- GCC Online Documentation
man g++
: 在你的 Linux 终端里直接输入这个命令,可以查看g++
的完整手册。