从Linux基础工具到编译调试、版本控制,一套完整的开发环境与工具链,是入门系统编程的必备基石。
1. 软件包管理器
1.1 核心概念
软件包:提前编译好的程序,类似 Windows 的 .exe 安装包。
包管理器:用于查找、下载、安装、卸载软件包的工具,类似手机应用商店。
CentOS/RHEL:yum (Yellowdog Updater, Modified)
Ubuntu/Debian:apt (Advanced Package Tool)
操作系统生态:决定系统易用性,包含社区论坛、官网文档、软件体系、维护更新速度、系统本身、用户群体。
1.2 软件包依赖
软件之间存在依赖关系(如你的软件依赖 libc.so,libc.so 又依赖 ssl.so),包管理器会自动解决依赖。
1.3 yum/apt 常用操作
查看软件包
bash
# CentOS
yum list | grep lrzsz
# Ubuntu
apt search lrzsz
apt show lrzsz
安装软件
bash
# CentOS
sudo yum install -y lrzsz
# Ubuntu
sudo apt install -y lrzsz
卸载软件
bash
# CentOS
sudo yum remove [-y] lrzsz
# Ubuntu
sudo apt remove [-y] lrzsz
注意事项:安装需要 sudo 或 root 权限,同一时间只能运行一个 yum/apt 进程。必须保证网络畅通(可 ping www.baidu.com 验证)。
1.4 安装源配置
CentOS:源文件路径 /etc/yum.repos.d/
Ubuntu:源文件路径 /etc/apt/sources.list 和 /etc/apt/sources.list.d/
安装扩展源(CentOS):sudo yum install -y epel-release
2. 编辑器 Vim
2.1 三种核心模式
命令模式 (Normal mode):默认进入,用于控制光标、删除、复制、切换模式。
插入模式 (Insert mode):用于输入文字,按 Esc 回到命令模式。
底行模式 (Last line mode):用于保存、退出、查找、替换,按 Shift + ; 进入。
2.2 模式切换
命令模式 → 插入模式:i (光标前) / a (光标后) / o (下一行)
插入模式 → 命令模式:Esc
命令模式 → 底行模式:Shift + ; (输入 :)
2.3 命令模式常用命令
光标移动
h/j/k/l 左/下/上/右移一格
G 跳转到文件末尾
gg 跳转到文件开头
$ 跳转到行尾
^ 跳转到行首
w 跳转到下一个单词开头
b 跳转到上一个单词开头
n\]G 跳转到第 n 行(如 15G)
#### 文本操作
x 删除光标后一个字符 X 删除光标前一个字符
dd 删除当前行 \[n\]dd 删除 n 行
yy 复制当前行 \[n\]yy 复制 n 行
p 粘贴复制的内容
u 撤销上一步操作 Ctrl + r 恢复撤销
r 替换单个字符 R 持续替换直到 Esc
### 2.4 底行模式常用命令
:w 保存文件
:q 退出 Vim
:wq 保存并退出
:q! 强制退出(不保存)
:set nu 显示行号
:\[n\] 跳转到第 n 行(如 :15)
/keyword 向后查找关键字 ; ?keyword 向前查找 ; n 查找下一个
### 2.5 Vim 配置
系统配置:/etc/vimrc
用户私有配置:\~/.vimrc
常用配置项:
```bash
syntax on " 语法高亮
set nu " 显示行号
set shiftwidth=4 " 缩进为4个空格
```
常用插件:TagList、WinManager(用于文件浏览和函数列表)
## 3. 编译器 gcc/g++
### 3.1 编译流程(4 阶段)
1. 预处理:宏替换、去注释、头文件展开、条件编译 → .i 文件
2. 编译:生成汇编语言 → .s 文件
3. 汇编:生成机器码 → .o 目标文件
4. 链接:生成可执行文件或库文件
### 3.2 核心编译选项
|-----------------|----------------------|-------------------------------------|
| 选项 | 作用 | 示例 |
| -E | 仅预处理,生成 .i 文件 | gcc -E hello.c -o hello.i |
| -S | 编译到汇编,生成 .s 文件 | gcc -S hello.i -o hello.s |
| -c | 汇编到目标代码,生成 .o 文件 | gcc -c hello.s -o hello.o |
| -o | 指定输出文件名 | gcc hello.o -o hello |
| -g | 生成调试信息(供 gdb 使用) | gcc -g hello.c -o hello |
| -static | 静态链接(将库代码打包进可执行文件) | gcc -static hello.c -o hello_static |
| -shared | 动态链接(默认,依赖系统动态库) | gcc -shared hello.c -o libhello.so |
| -O0/-O1/-O2/-O3 | 优化级别(O0 无优化,O3 最高优化) | gcc -O2 hello.c -o hello |
| -Wall | 生成所有警告信息 | gcc -Wall hello.c -o hello |
| -w | 不生成任何警告信息 | gcc -w hello.c -o hello |
### 3.3 静态链接 vs 动态链接
静态链接:
优点:运行时不依赖系统库,可移植性强,运行速度快
缺点:可执行文件体积大,库更新后需重新编译
动态链接:
优点:可执行文件体积小,库更新无需重新编译
缺点:运行时依赖系统动态库,移植性稍差
库文件后缀:
Linux:静态库 .a,动态库 .so
Windows:静态库 .lib,动态库 .dll
查看依赖库:ldd hello(查看可执行文件依赖的动态库)
### 3.4 静态库安装(CentOS)
```bash
sudo yum install glibc-static libstdc++-static -y
```
## 4. 自动化构建 make/Makefile
### 4.1 核心概念
make:命令工具,解释 Makefile 中的规则,实现自动化编译。
Makefile:文本文件,定义文件依赖关系和编译命令。
优势:一次编写,多次使用,自动判断哪些文件需要重新编译,提升开发效率。
### 4.2 基础 Makefile 示例
```bash
# 目标文件: 依赖文件
myproc:myproc.c
gcc -o myproc myproc.c # 注意:命令前必须是 Tab 键,不能是空格
.PHONY:clean # 声明 clean 为伪目标
clean:
rm -f myproc
```
依赖关系:myproc 依赖 myproc.c,若 myproc.c 比 myproc 新,则重新编译。
伪目标 .PHONY:避免和同名文件冲突,确保 make clean 总是执行。
### 4.3 多阶段依赖推导
```bash
myproc:myproc.o
gcc myproc.o -o myproc
myproc.o:myproc.s
gcc -c myproc.s -o myproc.o
myproc.s:myproc.i
gcc -S myproc.i -o myproc.s
myproc.i:myproc.c
gcc -E myproc.c -o myproc.i
.PHONY:clean
clean:
rm -f *.i *.s *.o myproc
```
make 会递归查找依赖,从 .c 开始,依次生成 .i → .s → .o → 可执行文件。
### 4.4 高级 Makefile 语法(变量与通配)
```bash
# 定义变量
BIN=proc.exe
CC=gcc
SRC=$(wildcard *.c) # 获取当前目录所有 .c 文件
OBJ=$(SRC:.c=.o) # 将 .c 替换为 .o,生成目标文件列表
LFLAGS=-o
FLAGS=-c
RM=rm -f
# 生成可执行文件
$(BIN):$(OBJ)
$(CC) $(LFLAGS) $@ $^ # $@=目标文件名, $^=所有依赖文件
@echo "linking ... $^ to $@"
# 模式规则:生成所有 .o 文件
%.o:%.c
$(CC) $(FLAGS) $< -o $@ # $<=第一个依赖文件
@echo "compling ... $< to $@"
.PHONY:clean test
clean:
$(RM) $(OBJ) $(BIN)
test:
@echo $(SRC)
@echo $(OBJ)
```
### 4.5 make 工作原理
1. 查找当前目录下的 Makefile 或 makefile。
2. 以第一个目标文件为最终目标。
3. 递归检查依赖文件的修改时间,判断是否需要重新编译。
4. 若依赖文件不存在,先生成依赖文件。
5. 执行编译命令生成最终目标。
## 5. Linux 系统程序:进度条与行缓冲区
### 5.1 行缓冲区现象
带 \\n 的 printf:printf("hello bite!\\n"); → 立即输出(\\n 刷新缓冲区)。
不带 \\n 的 printf:printf("hello bite!"); → 缓冲区满或程序结束才输出。
手动刷新缓冲区:fflush(stdout); → 强制输出缓冲区内容。
### 5.2 倒计时程序示例
```cpp
#include
-
添加文件到暂存区:
git add [文件名] # 添加单个文件
git add . # 添加当前目录所有文件 -
提交到本地仓库:git commit -m "提交日志(描述本次修改)"
-
推送到远程仓库:git push
6.5 其他常用命令
git status:查看文件状态
git log:查看提交历史
git pull:拉取远程仓库最新代码
.gitignore:指定不需要 Git 管理的文件(如日志、临时文件)
配置用户信息:
bash
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
7. 调试器 gdb/cgdb
7.1 编译调试版程序
必须添加 -g 选项生成调试信息:
bash
gcc -g mycmd.c -o mycmd # 生成带调试信息的可执行文件
7.2 启动与退出 gdb
bash
gdb [可执行文件名] # 启动 gdb
Ctrl + d 或 quit # 退出 gdb
7.3 核心调试命令
|--------------|-------------|------------------------|
| 命令 | 作用 | 示例 |
| list/l | 显示源码 | l main / l 10 |
| run/r | 运行程序 | r |
| next/n | 单步执行(不进入函数) | n |
| step/s | 单步执行(进入函数) | s |
| break/b | 设置断点 | b 24 / b main |
| info break/b | 查看断点信息 | info b |
| print/p | 打印变量/表达式 | p result / p start+end |
| set var | 修改变量值 | set var flag=1 |
| continue/c | 继续执行 | c |
| finish | 执行到函数返回 | finish |
| backtrace/bt | 查看函数调用栈 | bt |
| until | 执行到指定行 | until 14 |
| watch | 监视变量变化 | watch result |
7.4 调试技巧
watch 变量:当变量值变化时,gdb 会暂停程序并提示,适合排查变量被意外修改的问题。
set var 修改变量:在调试时临时改变变量值,验证问题原因。
cgdb:带界面的 gdb,更直观查看代码和调试信息,安装命令:
bash
# Ubuntu
sudo apt-get install -y cgdb
# CentOS
sudo yum install -y cgdb
7.5 调试示例(排查结果为 0 的问题)
cpp
// mycmd.c
#include <stdio.h>
int flag = 0; // 错误:flag 初始为 0
int Sum(int s, int e)
{
int result = 0;
for(int i = s; i <= e; i++)
{
result += i;
}
return result*flag; // 导致结果为 0
}
int main()
{
int start = 1;
int end = 100;
int n = Sum(start, end);
printf("result: %d\n", n);
return 0;
}
调试步骤:
-
gdb mycmd 启动调试。
-
b 24 在 int n = Sum(start, end); 处设置断点。
-
r 运行程序,触发断点。
-
s 进入 Sum 函数,n 单步执行,p result 查看累加结果。
-
p flag 发现 flag=0,set var flag=1 修改后,c 继续执行,结果恢复正常。
8. 补充知识点
条件编译应用场景:根据不同平台/环境编译不同代码(如 #ifdef linux)。
为什么要把语言变成汇编:汇编是机器码的文本表示,是 CPU 能直接执行的指令集,编译器将高级语言翻译成汇编,再转为机器码。
编译器自举:用编译器本身编译自己的源码,证明编译器能正确处理自身代码,是编译器成熟的标志。
9. 回车与换行
回车 \r:光标回到行首,不换行(老式打字机的"回车"动作)。
换行 \n:光标移到下一行(老式打字机的"换行"动作)。
Windows:\r\n 表示换行;Linux/macOS:\n 表示换行。
掌握这些Linux开发工具与核心知识点,不仅能搭建起高效的开发环境,更能帮你理解程序从编写到运行的完整逻辑,为后续系统编程与项目开发打下扎实根基。