使用命令行编译运行
当「一键编译运行」不能满足你的需求的时候,你可以直接通过命令自己控制编译运行的行为。
如果你需要安装编译器,请参考 编译器配置。
编译运行
假设有一个程序 a.cpp
,内容如下。
1 2 3 4 5 6 7 8 |
|
a.cpp
的程序到二进制程序 a
,并运行:
1 2 |
|
1 2 |
|
1 2 |
|
笔者解释一下这里的编译命令:
-g
表示开启调试。这意味着你可以使用gdb
等工具来调试他。-
-Wall
表示开启大多数警告。警告可以有效避免低级错误,我们举例来说:这种代码在老版本的1 2 3 4 5 6 7 8 9 10
#include <bits/stdc++.h> using namespace std; int factorials(int n) { if (n <= 1) return 1; else factorials(n - 1) * n; // oops, i forgot return } int main() { cout << factorials(5) << endl; }
g++
下是没有警告的;甚至由于编译器特性,计算结果与返回值默认放在eax
寄存器上,导致本地调试不会出现问题。然而,由于代码本身是存在 ub (undefined behavior,未定义行为) 的,优化器会默认有 ub 的代码是不会被运行的,因此在 OJ 上开启优化开关后运行出错。如果打开警告,编译器可以对这种情况进行提示。
1 2 3 4 5 6 7 8 9 10
~$ g++ a.cpp -o a -g ~$ g++ a.cpp -o a -g -Wall a.cpp: In function ‘int factorials(int)’: a.cpp:5:28: warning: value computed is not used [-Wunused-value] 5 | else factorials(n - 1) * n; // oops, i forgot return | ~~~~~~~~~~~~~~~~~~^~~ a.cpp:6:1: warning: control reaches end of non-void function [-Wreturn-type] 6 | } | ^ ~$
笔者通常使用的更多警告包括
-Wextra -Wconversion -Wshadow
。- 警告并不一定代表问题,例如开启
-Wconversion
后,比较int
和unsigned int
会导致一个警告。如果你不喜欢某些警告,可以仅开启需要的。 - 但是,编译器能起到有效 Warning 是编译型语言的优越性。强烈建议至少打开
-Wall
。
- 警告并不一定代表问题,例如开启
-
-std=c++17
表示采用 C++17 语言标准。这句话通常可以省略,除非你遇到了相关的 Compile Error。
文件输入输出
有时,我们会希望从一个文件里面读取输入文件,并输出到文件中。在不改动代码文件的情况下,你可以这么做:
1 |
|
1 |
|
对于使用 PowerShell 的 Windows 用户
PowerShell 的管道输入输出语法不一样,因此没法在 PowerShell 里运行以上命令。
要直接使用上面的命令,你可以在打开的 PowerShell 窗口里输入 cmd 来让 PowerShell 成为 cmd 的套皮。
1 |
|
Liunx / macOS 下测时
有时,我们会想测试代码运行效率。这种情况下,结合以上方法使用 time
命令将会非常方便。请注意,OJ 默认开启编译优化 O2,因此测时时应当也开启 O2。
1 2 |
|
如果使用 /usr/bin/time
甚至能粗略测出内存占用。
1 |
|
Todo
更换该页图片为代码块。
类似 /usr/bin/time -v
的用法在 macOS 下需要 brew install gnu-time
,需要补充。