第1篇 Linux下C语言基础 2
第1章 Linux简介 2
1.1 GNU简介 2
1.2 Linux简介 2
Linux发展史 2
Linux发行版 4
Linux内核版本 5
Linux与UNIX的关系 5
Linux在服务器方面的发展 5
Linux在嵌入式系统方面的发展 6
Linux在桌面系统方面的发展 7
1.3 Linux环境下的其他编程语言 7
C++ 7
Java 10
Perl 12
Python 13
Ruby 14
PHP 14
第2章 控制结构 17
2.1 goto语句 17
C语言中的无条件跳转 17
使用goto语句进行出错处理 18
出错处理的一般模型 20
2.2 C语言中的分支结构 21
分支结构的翻译 22
使用goto语句实现分支结构 23
2.3短路计算 24
短路计算 24
&&运算的短路计算 25
‖运算的短路计算 26
2.4 C语言中的循环结构 28
while循环 28
do…while循环 30
for循环 32
2.5 switch语句 34
switch语句的应用 34
使用goto语句实现switch语句 35
2.6优化控制结构 37
表达式优化——使用替换程序中的乘除法 37
表达式优化——常量折叠 38
表达式优化——使用数学公式 38
表达式优化——存储问题 40
分支优化——改变判断顺序 40
分支优化——使用switch语句 44
循环优化——一次性计算 46
第3章 C语言中的函数 49
3.1函数的本质 49
3.2变量的作用域和生命期 50
全局变量 50
局部变量 51
3.3变量的初始值 53
全局变量的初始值 53
局部变量的初始值 54
3.4与函数有关的优化 55
函数调用与程序优化 55
变量存储优化 58
3.5编写多文件程序——变量的存储类别 60
存储类别 60
static变量的作用——改变变量的生命期 60
static变量的作用——实现封装和模块化设计 63
3.6编写多文件的程序——链接的作用 66
链接多个文件 66
链接时符号解析规则 68
链接规则的应用 68
3.7可变参数 72
可变参数的概念 72
实现一个简单的可变参数的函数 73
可变参数实例 75
关于printf函数的疑问——缺少整型参数 80
关于printf函数的疑问——缺少字符串地址参数 81
第4章 C语言中的指针与字符串 84
4.1 sizeof运算符 84
sizeof运算符的应用——得到内置类型的大小 84
sizeof运算符的应用——得到复合类型的大小 85
4.2指针的应用 86
指针与别名陷阱 86
数组的指针 88
指针的指针 90
指针与参数传递 91
指针类型的意义 98
void*型指针 100
4.3函数的指针 103
C语言中的函数指针 103
函数指针的应用——回调函数 106
函数指针数组 111
4.4字符串 113
字符串与字符数组 113
字符串与指针 114
限定修饰符const 116
const关键字修饰指针——在指针定义之前 117
const关键字修饰指针——在指针定义之中 117
const关键字修饰指针——在指针定义之前和定义之中 118
使用const关键字的意义 119
第5章 C语言的高级技术 122
5.1结构体与共同体 122
结构体中成员变量的存储分布 122
内存对齐 123
5.2位运算 126
掩码运算 127
不安全的位运算 129
异或运算的特性 130
移位运算的陷阱 133
移位运算的实例 134
5.3预处理 136
常用的代码组织形式 136
调试开关 142
5.4 C99新标准关键字详解 145
inline关键字的概念 145
inline关键字实例 145
inline关键字使用总结 146
restrict关键字的概念 147
restrict关键字的应用 148
第2篇 C语言开发环境 152
第6章 vi与vim编辑器 152
6.1 vi编辑器入门 152
vi简介 152
vi的工作模式 152
6.2 vi一般操作 153
进入vi 153
文本插入操作 156
文本删除操作 158
文本复制操作 159
撤销命令 161
重复命令 162
退出vi 162
6.3 vi的增强操作 164
替换命令 164
光标移动 165
按行移动光标 166
按字移动光标 167
按句移动光标 168
按段移动光标 169
文本行的移动 169
文本的异行移动 170
屏幕滚动 171
查找命令 171
替换命令 173
窗口的切分 175
设置环境 176
第7章 gcc编译器 177
7.1初探gcc编译器 177
从经典的hello world开始 177
gcc编译流程 178
7.2 gcc常用选项 179
gcc常用选项汇总 179
-c选项 179
-S选项 180
-E选项 182
-o选项 182
-I选项 183
-g选项 183
7.3链接原理 183
链接器的任务 183
目标文件 184
ELF格式的可重定位目标文件 185
目标文件中的符号表 187
重定位的概念 191
符号的重定位信息 192
7.4关于库 192
使用库的优势 192
静态库的概念 194
创建静态库 194
使用静态库 195
动态库的概念 197
创建动态库 197
使用动态库 199
7.5 gcc工具链 201
第8章 makefile 203
8.1 makefile文件入门 203
makefile文件的组成内容 203
makefile文件包含 203
make工具的退出码 204
8.2书写makefile规则 205
使用基本规则 205
使用隐式规则 206
使用伪目标 207
使用通配符 209
搜索源文件 209
8.3使用命令 210
显示命令 211
执行命令 211
命令出错 212
8.4使用变量 213
使用普通变量 213
变量中的变量 215
追加变量的值 217
自动化变量 218
8.5使用条件判断 219
条件表达式 219
表达式实例 221
8.6使用函数 221
函数调用的语法 222
字符串处理函数 222
文件名操作函数 229
foreach函数 233
if函数 233
call函数 234
origin函数 235
shell函数 235
8.7 makefile实例 236
makefile实例——项目中的总makefile 236
makefile实例——makefile模板 238
第9章 gdb 240
9.1列出源程序 240
不带参数的list命令 240
带一个参数的list命令 241
带两个参数的list命令 242
9.2运行程序的命令 243
9.3操作断点的命令 244
设置断点 244
显示当前gdb的断点信息 247
删除指定的断点 247
禁止或启用断点 248
清除断点 248
观察点 249
设置断点实例 250
9.4查看运行时数据 254
数据观察命令 254
对程序中函数的调用 256
查看表达式的值 256
查看数组的值 257
变量的输出格式 257
查看内存 258
自动显示变量 259
设置显示选项 263
显示变量的历史记录 265
查看寄存器 266
查看使用gdb环境变量 267
查看数据实例 268
9.5改变程序的执行 273
修改变量的值 273
跳转执行 274
信号的产生及处理 275
强制调用函数 276
强制函数返回 276
9.6 gdb高级应用 278
产生core文件 278
跟踪栈上数据 278
绑定运行进程 281
源文件搜索 283
机器语言工具 283
其他有用的调试命令 284
第3篇 Linux进程操作 288
第10章 进程环境 288
10.1程序的启动和退出 288
在shell中启动一个程序 288
加载一个程序 289
加载地址 290
退出程序 291
进程终止处理函数 292
10.2 Linux进程内存管理 294
数据的内部存储 294
C程序的存储布局——代码段 296
C程序的存储布局——数据段和缓冲段 298
C程序的存储布局——栈 299
C程序的存储布局——堆 301
常量的存储 302
动态内存管理 302
动态内存分配的深入研究 305
10.3 shell环境 309
命令行参数 310
得到程序文件名 311
环境变量 312
得到指定的环境变量 314
设置一个环境变量 315
得到进程结束状态 320
使用errno调试程序 322
输出错误原因 324
10.4全局跳转 325
局部跳转的局限性 326
使用全局跳转 327
使用全局跳转代替局部跳转 329
第11章 进程控制 332
11.1进程标识符 332
进程ID 332
进程中重要的ID值 333
11.2进程操作 335
创建一个进程 335
父子进程的共享资源 337
fork函数的出错情况 340
创建一个共享空间的子进程 341
在函数内部调用vfork函数 342
退出进程 344
使用exit函数检查进程出错信息 345
exit函数与内核函数的关系 346
设置进程所有者 346
调试多进程——设置跟踪流 348
调试多进程——使用gdb的attach命令 348
11.3执行程序 349
执行一个新程序 350
执行解释器文件 352
在程序中执行shell命令 355
实现system函数 356
11.4关系操作 358
等待进程退出 358
等待指定的进程 362
僵尸进程的概念 364
产生一个僵尸进程 364
避免僵尸进程的产生 366
输出进程统计信息 369
第12章 时间和日历历程 372
12.1系统时间 372
12.2日历时间 374
第13章 信号及信号处理 378
13.1信号的基础 378
信号的基本概念 378
产生信号 379
处理信号 379
常用信号的使用方法 380
13.2信号的影响 382
重入 382
原子操作 385
中断系统调用 387
13.3信号处理函数 387
设置信号处理函数 387
发送信号 391
向进程本身发送信号 392
设置Linux定时器 393
定时等待I/O 395
挂起进程 397
进程休眠 399
13.4信号集与屏蔽信号 402
信号集和信号集处理函数 402
屏蔽信号 404
处理未决信号 406
高级信号注册函数 409
信号选项实例——SA_NOCLDWAIT选项 410
信号选项实例——SA_NODEFFER选项 412
信号选项实例——SA_RESETHAND选项 414
第14章 进程间通信 416
14.1进程间通信概述 416
进程间通信简介 416
进程间通信的难点 417
IPC的多种方式 417
14.2管道 418
管道的概念 418
匿名半双工管道 418
匿名半双工管道的读写操作 420
创建管道的标准库函数 423
14.3 FIFO管道 426
FIFO的概念 426
创建FIFO 427
FIFO的读写操作 428
FIFO的缺点 432
14.4 System V IPC/POSIX IPC 433
IPC对象的概念 433
IPC对象的问题 435
IPC对象系统命令 435
14.5共享内存 436
共享内存的概念 436
共享内存的创建 437
共享内存的操作 439
共享内存使用注意事项 442
14.6信号量 442
信号量的概念 442
信号量的创建 443
信号量集的操作 446
14.7消息队列 448
消息队列的概念 448
创建消息队列 449
读写消息队列 452
第15章 线程 456
15.1线程与进程 456
线程的概念 456
线程的优势 457
15.2线程标识符 458
15.3线程基本操作 458
创建线程 458
向线程体函数传递参数 460
线程访问资源的限制 462
终止线程 466
正确得到线程退出信息的方法 470
取消一个线程的运行 473
线程退出函数 476
第16章 线程高级操作 480
16.1线程同步——使用互斥量 480
初始化与销毁互斥量 480
得到与释放互斥量 481
使用互斥量的实例 482
16.2线程同步——使用读写锁 489
初始化与销毁读写锁 489
得到与释放互斥锁 490
使用互斥量与读写锁的比较 491
16.3线程属性 499
创建和销毁属性结构 499
线程的分离状态 500
分离一个已经创建的线程 502
线程栈的属性 503
第4篇 Linux文件操作 508
第17章 文件I/O 508
17.1文件描述符的概念 508
17.2文件I/O操作 508
打开一个文件 508
打开文件的出错情况 512
关闭一个文件 513
创建一个新文件 514
文件定位 515
文件截短 517
清空一个文件 521
文件的读写操作 523
文件同步 527
17.3文件描述符操作 529
复制文件描述符 529
1/O重定向概念及其应用 531
控制文件 534
修改打开文件的文件状态 535
17.4非阻塞文件I/O 538
非阻塞I/O的概念 538
以非阻塞方式打开文件 539
将一个打开文件设置为非阻塞方式 541
17.5内存映射I/O 543
内存映射I/O的概念 543
创建一个内存映射 544
撤销一个内存映射 547
内存映射同步 549
更改内存映射的权限 552
第18章 文件管理 555
18.1文件状态 555
18.2文件类型 556
18.3文件权限 559
访问权限 559
设置用户ID位和设置组ID位 561
设置用户ID位的作用 562
使用设置用户ID位的实例 562
18.4文件权限操作 566
测试文件访问权限 566
设置用户ID位与文件权限测试 568
使用文件权限屏蔽字 569
在shell中使用文件权限屏蔽字 570
在程序中使用文件权限屏蔽字 570
改变文件访问权限 572
在shell中改变文件权限 573
在程序中改变文件权限 574
改变一个打开的文件权限 575
18.5文件系统结构 579
18.6文件的硬链接 583
创建一个硬链接 584
删除一个硬链接 585
18.7改变文件所有者 589
18.8操作文件的时间 593
第19章 目录操作 597
19.1目录的权限 597
目录的访问权限 597
测试目录的访问权限 598
19.2目录操作 599
创建一个目录 599
删除一个目录 600
目录项结构 601
打开与关闭目录 602
读目录 603
读目录操作的实例——实现自己的ls命令 606
得到目录文件的读写位置 608
定位目录 610
回卷目录文件 611
19.3进程的工作目录 612
工作目录的概念 613
改变进程的工作目录 613
得到进程的当前工作目录 615
子进程工作目录对父进程的影响 618
第20章 特殊文件 622
20.1符号链接操作 622
符号链接 622
符号链接的功能 622
创建符号链接 623
创建指向不存在文件的符号链接 625
读写符号链接的目的文件 626
读写多重符号链接的目的文件 628
读写符号链接 630
取得符号链接的状态 633
更改符号链接的所有者 637
20.2 proc文件系统 642
proc文件系统 642
常用的内核信息 642
读取内核信息 644
进程状态信息 652
读取进程状态 653
proc文件系统变成实例——实现自己的ps命令 655
第21章 基于流的I/O 658
21.1流与缓冲 658
21.2基于流的文件操作 660
打开和关闭流 660
文件内容的冲洗 662
以字符为单位读写数据 664
以行为单位读写数据 666
gets函数的漏洞 667
逐行读取文件内容 668
输出xml形式的配置文件 669
读写数据块 671
文件读写实例——实现cp命令 672
文件读写实例——字符统计 674
文件读写实例——目录下所有文件的字符统计 675
第5篇 Linux网络编程 680
第22章 TCP和UDP协议 680
22.1计算机网络的体系结构简介 680
计算机网络体系结构简介 680
OSI参考模型中各层功能描述 680
TCP/IP参考模型的各层功能描述 681
面向连接服务和无连接服务 682
22.2客户/服务器方式简介 682
22.3用户数据报协议UDP 683
用户数据报的格式 683
用户数据报检验和的计算 684
UDP用户数据报的特性及用途 686
22.4传输控制协议TCP 686
TCP简介 686
TCP报文段的首部 686
TCP数据编号与确认 688
TCP的流量控制与拥塞控制 688
TCP的运输连接管理 690
第23章 网络编程基础 693
23.1套接字概念 693
23.2准备工作 694
字节序 694
地址格式 695
地址形式转换 697
获得主机信息 698
地址映射 700
23.3套接字基础编程 701
建立和销毁套接字描述符 701
地址绑定 703
建立一个连接 704
最简单的网络应用程序——服务器端 707
最简单的网络应用程序——客户端 710
使用文件读写函数读写套接字 713
使用完整读写函数的网络应用程序 716
面向连接的数据传输 720
面向连接的网络应用程序——服务器端 721
面向连接的网络应用程序——客户端 724
无连接的数据传输 727
无连接的网络应用程序——服务器端 729
无连接的网络应用程序——客户端 731
23.4非阻塞套接字 734
非阻塞网络应用程序——服务器端 734
非阻塞网络应用程序——客户端 737
第24章 网络编程进阶 740
24.1套接字编程深入 740
bind函数的作用 740
并发服务器 741
UDP协议的connect函数应用 743
24.2多路选择I/O 746
多路选择I/O的概念 746
实现多路选择I/O 747
使用多路选择I/O处理多个连接 750
屏蔽信号的多路选择I/O 754
对比select函数和pselect函数 755
轮询I/O 758
24.3非网络通信套接字 759
非命名UNIX域套接字 759
命名UNIX域套接字 761
UNIX域套接字实例——服务器端 762
UNIX域套接字实例——客户端 766
第25章 网络编程实例——实现文件传输程序 769
25.1程序设计 769
整体程序设计 769
客户端程序设计 769
服务器端程序设计 770
25.2文件传输程序的实现 773
客户端程序的实现——头文件 773
客户端程序的实现——程序主函数 774
客户端程序的实现——命令拆分函数 777
客户端程序的实现——命令处理模块 779
服务器端程序的实现——头文件 790
服务器端程序的实现——程序主函数 791
服务器端程序的实现——客户端命令处理模块 794
25.3测试和验证 801
第26章 网络编程实例——简单的Web服务器 802
26.1程序设计 802
整体程序设计 802
步骤1——解析客户端发送的内容 803
步骤2——寻找客户端需要的文件 804
步骤3——将客户端信息返回 804
26.2 Web服务器的实现 805
Web服务器程序的实现——头文件 806
Web服务器程序的实现——程序主函数 806
Web服务器程序的实现——请求处理模块 811
26.3测试和验证 816
第6篇 shell脚本知识 818
第27章 shell脚本基础 818
27.1编写最简单的shell脚本 818
使用shell脚本的原因 818
脚本内容 819
运行一段脚本 820
27.2 shell中的变量 821
用户自定义变量 821
引用变量 823
为表达式求值 824
变量的类型 826
操作自定义变量 828
位置变量 830
重新分配位置变量 831
27.3退出状态 833
27.4条件测试 835
测试文件状态 835
测试时使用逻辑操作符 837
字符串测试 839
测试数值 841
第28章 shell脚本中的控制结构 844
28.1 shell脚本中的命令替换 844
28.2分支结构 845
if/else分支结构 845
多重分支结构 847
使用case结构的分支语句 848
在case语句中使用逻辑表达式 851
28.3条件测试命令的值 853
测试整数与字符串 853
测试字符串和空值 854
测试未初始化的变量 855
测试“false”的值 856
28.4循环结构 857
while循环结构 858
until循环结构 861
for循环结构 864
break和continue命令 866
28.5定义函数和使用函数 869