1. 1.入门
1.1. C语言怎样工作
1.2. 一个完整的C程序
1.2.1. main函数
1.2.2. 格式化输出
1.2.3. 编译&运行程序
1.3. 字符串
1.3.1. 字符数组
1.3.1.1. 尾0的处理
1.4. 等号
1.4.1. =
1.4.2. ==
1.4.3. +=/-=
1.4.3.1. ++/--
1.5. 语句
1.5.1. if...else..
1.5.2. 花括号
1.6. 布尔运算
1.6.1. &&
1.6.2. ||
1.6.3. !
1.6.4. true=1, false=0
1.7. gcc
1.8. switch语句
1.9. 循环
1.9.1. while
1.9.1.1. do...while
1.9.2. for
1.9.3. break
1.10. 函数
1.10.1. void函数
1.11. 连锁赋值
2. 2.存储器&指针
2.1. 指针的好处
2.2. 存储器剖面图
2.3. 传递参数
2.3.1. 按值
2.3.2. 传指针
2.3.2.1. 共享存储器
2.4. 怎样使用指针
2.4.1. 得到变量的地址
2.4.2. 读地址中的内容
2.4.3. 改变地址中的内容
2.5. 数组与指针
2.5.1. 把字符串传给函数
2.5.1.1. 传指针
2.5.2. 数组变量与指针的区别
2.5.2.1. 指针退化
2.5.3. 为什么数组从0开始?
2.6. 为什么指针有类型?
2.7. 通过指针输入数据
2.7.1. scanf()
2.7.1.1. 缓冲区溢出
2.7.2. fgets()
2.7.3. gets()
2.8. char *a与char a[]的区别
2.8.1. 字符串字面值
3. 2.5.字符串理论
3.1. 数组的数组
3.2. string.h
3.2.1. strchr()
3.2.2. strcmp()
3.2.3. strstr()
3.2.4. strcpy()
3.2.5. strlen()
3.2.6. strcat()
3.3. 指针数组
4. 3.创建小工具
4.1. 为什么需要小工具?
4.2. 重定向
4.2.1. 标准输入(stdin)
4.2.1.1. <
4.2.2. 标准输出(stdout)
4.2.2.1. >
4.2.3. 标准错误(stderr)
4.2.3.1. 2>
4.3. fprintf():往数据流打印
4.4. 操作系统
4.5. 复用小工具
4.5.1. 文件+小工具
4.6. 小工具设计原则
4.7. 管道
4.7.1. p1 | p2
4.8. 自定义数据流
4.9. 命令行参数
4.9.1. 用getopt()解析命令行参数
5. 4. 使用多个源文件
5.1. 数据类型
5.1.1. char
5.1.2. int
5.1.3. short
5.1.4. long
5.1.5. float
5.1.6. double
5.2. 类型转换
5.3. 类型修饰符
5.3.1. unsigned
5.3.2. long
5.4. 找出数据类型的大小
5.5. 函数声明&定义
5.5.1. 顺序问题
5.5.2. 头文件
5.6. 共享代码
5.6.1. 多文件
5.6.2. 共享变量
5.6.2.1. extern
5.6.3. 共享代码的头文件
5.7. 编译的流程
5.7.1. 预处理
5.7.2. 编译
5.7.3. 汇编
5.7.4. 链接
5.8. 不必每次重新编译所有文件
5.8.1. 编译目标文件
5.8.1.1. gcc -c *.c
5.8.2. 链接
5.8.2.1. gcc *.o -o name
5.9. 使用make自动化编译
5.9.1. makefile文件
5.9.1.1. 依赖规则
5.9.1.2. 依赖项
6. 5.结构、联合、位字段
6.1. 结构(struct)
6.1.1. 打包数据传给函数
6.1.2. 和数组的区别
6.1.2.1. 定长
6.1.2.2. 按名访问数据
6.1.3. 读取字段
6.1.3.1. a.b
6.1.4. 结构中的结构
6.1.5. typedef
6.1.6. 更新结构
6.1.6.1. 通过结构指针
6.1.7. (*t).a和*t.a的区别
6.1.8. ->
6.2. 联合(union)
6.2.1. 不同类型的数据
6.2.2. 更好地利用空间
6.2.3. 表示和使用
6.2.3.1. C89
6.2.3.1.1. quantity q = {3};
6.2.3.2. 指定初始化
6.2.3.2.1. .field = 2
6.2.3.3. 点表示法
6.2.3.3.1. b.field = 3
6.2.4. 和结构一起使用
6.3. 枚举(enum)
6.3.1. 保存符号
6.4. 位字段
6.4.1. 表示true/false更节省空间
7. 6.数据结构与动态存储
7.1. 链表
7.1.1. 允许插入
7.1.2. 递归结构
7.2. 动态存储
7.2.1. 创建
7.2.1.1. malloc()
7.2.2. 释放
7.2.2.1. free()
7.3. 堆和栈的区别
7.4. 数据结构
7.4.1. 相联数组
7.4.2. 双向链表
7.4.3. 链表
7.4.4. 二叉树
7.5. 存储器泄漏
7.5.1. 使用valgrind检查泄漏
8. 7.高级函数
8.1. 函数指针
8.1.1. 向函数代码传代码
8.1.2. 为什么C语言没有函数类型?
8.1.3. 函数指针编写指南
8.2. 排序任何类型的数据
8.2.1. C标准库排序函数
8.2.1.1. qsort()
8.2.2. 比较器函数
8.3. 用枚举类型+函数指针数组代替switch
8.4. 可变参数函数
8.4.1. stdarg.h
8.4.1.1. va_list()
8.4.1.2. va_start()
8.4.1.3. va_arg()
8.4.1.4. va_end()
8.5. 宏(macro)和函数的区别
9. Lab 3: Blasteroid
9.1. 经典街机打飞机
10. Lab 2: OpenCV
10.1. 监控摄像头
11. Lab 1: Arduino
11.1. 给花浇水的装置
12. 8.静态库&动态库
12.1. 共享目标文件
12.1.1. 告诉编译器头文件
12.1.1.1. -I/header.h
12.1.2. 共享一批目标文件
12.1.2.1. 存档(.a文件)
12.1.2.2. ar命令打包
12.1.3. 告诉编译器库
12.1.3.1. -L./libs
12.2. 连接器
12.3. 动态链接
12.3.1. Mac
12.3.1.1. 绝对路径
12.3.2. Linux
12.3.2.1. 设置环境变量LD_LIBRARY_PATH
12.3.3. WIndows
12.3.3.1. 设置PATH
12.4. 动态库与静态库的比较
13. 9.进程&系统调用
13.1. 什么是系统调用
13.2. system()
13.3. 什么是内核
13.4. 进程
13.5. exec()
13.5.1. execl()
13.5.2. exclp()
13.5.3. execle()
13.6. 出错处理
13.6.1. errno
13.6.1.1. strerror()
13.7. fork()
13.7.1. 子进程
13.7.1.1. return 0
13.7.2. 父进程
14. 10.进程间通信
14.1. 文件描述符
14.1.1. 文件描述符表
14.1.2. 重定向修改数据流
14.1.3. fileno()返回描述符号
14.1.4. dup2()复制数据流
14.2. 错误处理函数
14.2.1. exit()
14.3. waitpid()
14.3.1. 进程号
14.3.2. 退出信息
14.3.2.1. WEXITSTATUS(pid_status)
14.3.3. 选项
14.4. 用管道连接父子进程
14.4.1. 父进程
14.4.1.1. 通过fd[1]写管道
14.4.2. 子进程
14.4.2.1. 通过fd[0]读管道
14.5. 信号
14.5.1. 信号处理器
14.5.2. sigaction
14.5.2.1. 包装器
14.5.3. 用sigaction()来注册sigaction
14.5.3.1. 信号号码
14.5.3.2. 新动作
14.5.3.3. 旧动作
14.5.4. 操作系统会发出的信号
14.5.4.1. SIGINT
14.5.4.2. SIGQUIT
14.5.4.3. SIGFPE
14.5.4.4. SIGSEGV
14.5.4.5. SIGTRAP
14.5.4.6. SIGWINCH
14.5.4.7. SIGTERM
14.5.4.8. SIGPIPE
14.5.5. 杀死进程
14.5.6. raise()
14.5.6.1. 信号升级
14.5.6.2. 自己给自己发送信号
14.5.7. 定时器信号
14.5.7.1. SIGALRM
14.5.7.2. sleep()
15. 11.套接字&网络
15.1. 服务器
15.1.1. 流程(BLAB)
15.1.1.1. 绑定端口
15.1.1.1.1. bind()
15.1.1.2. 监听
15.1.1.2.1. listen()
15.1.1.3. 接受连接
15.1.1.3.1. accept()
15.1.1.4. 开始对话
15.1.2. 用send()往客户端写数据
15.1.3. 用recv()从客户端读数据
15.1.3.1. 字符串以\r\n结尾
15.1.4. 重复使用端口
15.1.4.1. setsocketopt()
15.2. 客户端
15.2.1. 多客户端
15.2.1.1. fork()
15.2.2. 互联网客户端
15.2.2.1. HTTP协议
15.2.2.1.1. GET
15.2.2.1.2. 主机名
15.2.2.1.3. 空行
15.2.2.2. 流程
15.2.2.2.1. 连接远程端口
15.2.2.2.2. 开始对话
15.3. 协议
16. 12.线程
16.1. 进程与线程
16.2. 创建线程
16.2.1. POSIX线程库
16.2.1.1. pthread.h
16.2.2. pthread_create()
16.2.3. pthread_join()
16.3. 线程安全
16.3.1. 互斥锁(mutex)
16.3.1.1. pthread_mutex_t