编辑
缩排
为了使C源代码更加整洁易读,可以使用一些工具来自动格式化代码,例如cb
(C程序美化器)、bcpp
(C++美化器)和indent
等。
编译
编译并链接C文件
gcc hello.c -o hello
将 hello.c
编译并链接成可执行文件 hello
指定输出文件名
gcc -o hello hello.c
与上一条命令相同,明确指定了输出文件名为 hello
。
预处理
gcc -E hello.c -o hello.i
只进行预处理阶段,生成预处理后的文件 hello.i
。
生成汇编代码
gcc -S hello.i -o hello.s
将预处理后的文件 hello.i
编译成汇编代码文件 hello.s
。
生成目标文件
gcc -c hello.s -o hello.o
将汇编代码文件 hello.s
汇编成目标文件 hello.o
。
链接目标文件
gcc hello.o -o hello
将目标文件 hello.o
链接成最终的可执行文件 hello
。
指定输入文件类型
gcc -xc hello.tom
强制将 hello.tom
作为C语言源文件处理。-xc
选项告诉 gcc
将输入文件视为C语言源文件,即使其扩展名不是 .c
。
-
-w
关闭所有的警告信息。这对于忽略所有警告并专注于错误信息的情况非常有用,但通常不推荐这样做,因为警告往往能帮助发现潜在的问题。 -
-Wall
打开许多常见的警告信息,但并不是所有的警告。这是最常用的选项之一,因为它能够捕获大多数常见的编程错误和不良实践。 -
-Wno-
可以后面接具体的警告名称来关闭特定的警告。例如,-Wno-unused
会关闭未使用的变量或函数的警告。 -
-Wall -Wno-unused
即使开启了-Wall
,也可以通过-Wno-unused
来关闭未使用的变量或函数的警告。这样可以保持其他警告开启,同时忽略某些特定的警告。 -
-Wall -Wno-implicit
关闭隐式函数声明的警告。隐式函数声明是指没有显式声明就调用的函数,默认情况下 GCC 会发出警告,因为这可能导致类型不匹配的问题。 -
-Wall -Werror
将所有的警告当作错误处理。这意味着任何警告都会导致编译失败。这对于确保代码质量非常有用,特别是在持续集成环境中,可以强制开发者修复所有警告。 -
-Wall -Wextra
在-Wall
的基础上增加更多的警告信息。-Wextra
会启用一些额外的警告,比如未初始化的变量等,这些警告在-Wall
中是默认关闭的。
库文件
库文件是包含预编译代码的文件,这些代码可以被多个程序重复使用。库文件通常分为静态库和动态库两大类。
-
静态库:
- 静态库在编译阶段会被链接到目标代码中,成为可执行文件的一部分。这意味着每次创建可执行文件时,静态库中的代码都会被复制一份到最终的二进制文件中。
- 静态库的扩展名通常是 .a(在Unix/Linux系统)或 .lib(在Windows系统)。
-
动态库:
- 动态库(也称为共享库)在程序运行时才被加载到内存中。多个使用相同动态库的程序可以共享内存中的同一份副本,这有助于节省系统资源。
- 在Unix/Linux系统中,动态库的扩展名通常是 .so;而在Windows系统中,则是 .dll。
调试
编译源代码
gcc -g string-debug.c -o a.out
-
-g
选项告诉gcc
为生成的可执行文件添加调试信息。 -
-o a.out
指定输出文件名为a.out
。
2. 启动 GDB 并加载可执行文件
gdb a.out
这会启动 GDB 并加载 a.out
可执行文件。
3. 装入被调试的可执行文件
file a.out
虽然你在启动 GDB 时已经指定了 a.out
,但这个命令可以确保当前调试的是正确的文件。
4. 列出源代码
list
这会显示当前文件的前 10 行源代码。你可以使用 list n
来显示从第 n
行开始的代码。
5. 运行程序
run
这会启动程序并运行直到遇到断点或异常。
6. 查看调用栈
where
这会显示当前的调用栈,帮助你了解程序的执行路径。
7. 打印变量值
print string
这会显示 string
变量的当前值。
8. 设置断点
break string-debug.c:7
这会在 string-debug.c
文件的第 7 行设置一个断点。
9. 再次运行程序
run
这会重新启动程序,并在设置的断点处暂停。
10. 修改变量值
set variable string=(char*)malloc(100)
这会将 string
变量的值设置为通过 malloc
分配的 100 字节的内存地址。
11. 单步执行
next
这会执行下一行代码,但不会进入函数内部。如果你希望进入函数内部,可以使用 step
命令。