目录(完整版)
引子
让大脑重视 C 语言。现在你正试着学习某些东西,为了不让学习卡壳,你的大脑也在帮你的忙,大脑在想:“最好把空间留给重要的事,比如什么动物是危险的?裸体滑雪是不是一个坏主意?”那么怎么才能欺骗你的大脑,让它认为学好 C 关系到你下半生的幸福呢?
本书为谁而写
我们知道你在想什么
元认知
驯服你的大脑
用户须知
技术审校团队
致谢
1 C 语言入门
进入 C 语言的世界
想知道计算机在想什么?
你需要为一款新游戏编写高性能的代码吗?你需要为 Arduino 编程吗?你需要在 iPhone 应用中使用高级的第三方库吗?如果是的话,C 语言就可以帮上忙了。相比其他大多数语言,C 语言的工作层次更低,因此理解 C 语言可以让你更清楚程序在运行时到底发生了什么,C 语言还可以帮助你更好地理解其他语言。来吧,拿起编译器,很快你就能入门了。
C 语言用来创建空间小、速度快的程序
完整的 C 程序长啥样?
如何运行程序?
两类命令
到目前为止的代码
用 C 语言算牌?
布尔运算
现在的代码
随时转向的命运列车
有时一次还不够……
所有循环的结构都相同……
用 break 语句退出循环……
C 语言工具箱
2 存储器和指针
指向何方?
如果真的想玩转 C 语言,就需要理解 C 语言如何操纵存储器。
C 语言在如何使用存储器方面赋予了你更多的掌控权。在本章中,你将揭开存储器神秘的面纱,看到读写变量时到底发生了什么;学习数组的工作原理,以及怎样避免烦人的存储器错误;最重要的是,你将看到掌握指针和存储器寻址对成为一名地道的 C 程序员来讲有多么重要。
C 代码包含指针
深入挖掘存储器
和指针起航
试着传递指向变量的指针
使用存储器指针
怎么把字符串传给函数?
数组变量好比指针……
运行代码时,计算机在想什么
数组变量与指针又不完全相同
为什么数组从 0 开始
为什么指针有类型
用指针输入数据
使用 scanf() 时要小心
除了 scanf() 还可以用 fgets()
字符串字面值不能更新
如果想修改字符串,就复制它
把存储器保存在大脑里
C 语言工具箱
2.5 字符串
字符串原理
字符串不只是用来读取的。
在 C 语言中字符串其实就是 char 数组,这你已经知道了,问题是字符串能用来干嘛?该 string.h 出场了。string.h 是 C 标准库的一员,它负责处理字符串。如果想要连接、比较或复制字符串,string.h 中的函数就可以派上用场了。在本章中,你将学会如何创建字符串数组,并近距离观察如何使用 strstr() 函数搜索字符串。
不顾一切找 Frank
创建数组的数组
找到包含搜索文本的字符串
使用 strstr() 函数
该审查代码了
“数组的数组”和“指针的数组”
C 语言工具箱
3 创建小工具
做一件事并把它做好
操作系统都有小工具。
C 语言小工具执行特定的小任务,例如读写文件、过滤数据。如果想要完成更复杂的任务,可以把多个工具链接在一起。那么如何构建小工具呢?本章中,你会看到创建小工具的基本要素并学会控制命令行选项、操纵信息流、重定向,并很快建立自己的工具。
小工具可以解决大问题
程序如何工作
但没有使用文件……
可以用重定向
隆重推出标准错误
默认情况下,标准错误会发送到显示器
fprintf() 打印到数据流
用 fprintf() 修改代码吧
灵活的小工具
切莫修改 geo2json 工具
一个任务对应一个工具
用管道连接输入与输出
bermuda 工具
输出多个文件
创建自己的数据流
main() 可以做得更多
由库代劳
C 语言工具箱
4 使用多个源文件
分而治之
大程序不等于大源文件。
你能想象一个企业级的程序如果只有一个源文件,维护起来有多么困难与耗时吗?在本章中,你将学习怎样把源代码分解为易于管理的小模块,然后把它们合成一个大程序,同时还将了解数据类型的更多细节,并结识一个新朋友:make 。
简明数据类型指南
勿以小杯盛大物
使用类型转换把 float 值存进整型变量
不好啦,兼职演员来了……
代码到底怎么了
编译器不喜欢惊喜
声明与定义分离
创建第一个头文件
如果有共同特性……
把代码分成多个文件
编译的幕后花絮
共享代码需要自己的头文件
又不是造火箭……还真是!
不要重新编译所有文件
首先,把源代码编译为目标文件
记不住修改了哪些文件
用 make 工具自动化构建
make 是如何工作的
用 makefile 向 make 描述代码
火箭升空!
C 语言工具箱
C 语言实验室 1
Arduino
你可曾想过,你的植物告诉你它需要浇水?有了 Arduino,植物就可以开口了!本实验中,你将创建一个由 Arduino 驱动的植物监控器,全用 C 语言来写。
5 结构、联合与位字段
创建自己的结构
生活可比数字复杂多了。
到目前为止,你只接触过 C 语言的基本数据类型,但如果想表示数字、文本以外的其他东西呢,或为现实世界中的事物建立模型,怎么办?结构将帮你创建自己的结构,模拟现实世界中错综复杂的事物。在本章中,你将学习如何把基本数据类型组成结构以及用联合处理生活的不确定性。如果你想简单地模拟“是”或“非”,可以用位字段。
有时要传很多数据
窃窃私语
用结构创建结构化数据类型
只要把“鱼”给函数就行了
使用“.”运算符读取结构字段
结构中的结构
如何更新结构
代码克隆了乌龟
你需要结构指针
(*t).age 和*t.age
同一类事物,不同数据类型
联合可以有效使用存储器空间
如何使用联合
枚举变量保存符号
有时你想控制某一位
位字段的位数可调
C 语言工具箱
6 数据结构与动态存储
牵线搭桥
一个结构根本不够。
为了模拟复杂的数据需求,通常需要把结构链接在一起。在本章中,你将学习如何用结构指针把自定义数据类型连接成复杂的大型数据结构,将通过创建链表来探索其中的基本原理;同时还将通过在堆上动态地分配空间来学习如何让数据结构处理可变数量的数据,并在完成工作后释放空间;如果你嫌清理工作太麻烦,可以学习一下怎么用 valgrind 。
保存可变数量的数据
链表就是一连串的数据
在链表中插入数据
创建递归结构
用 C 语言创建岛屿……
在链表中插入值
用堆进行动态存储
有用有还
用 malloc() 申请存储器……
用 strdup() 修复代码
用完后释放存储器
SPIES 系统综述
软件取证:使用 valgrind
反复使用 valgrind ,收集更多证据
推敲证据
最终审判
C 语言工具箱
7 高级函数
发挥函数的极限
基本函数很好用,但有时需要更多功能。
到目前为止,你只关注了一些基本的东西,为了达成比较器函数排序,最后还将学会使用可变参数函数让代目标,需要更多的功能与灵活性。本章你将学习如何把函数作为参数传递,从而提高代码的智商,并学会用码伸缩自如。
寻找真命天子……
把代码传给函数
把函数名告诉 find()
函数名是指向函数的指针 ……
……没有函数类型
如何创建函数指针
用 C 标准库排序
用函数指针设置顺序
分手信自动生成器
创建函数指针数组
让函数能伸能缩
C 语言工具箱
8 静态库与动态库
热插拔代码
你已经见识过标准库的威力。
是时候在代码中发挥这种威力了。在本章中,你将学会创建自己的库,以及在多个程序中复用相同代码;还将掌握编程大师的秘诀——通过动态库在运行时共享代码;最后你将写出易于扩展并可以有效管理的代码。
值得信赖的代码
尖括号代表标准头文件
如何共享代码?
共享.h 头文件
用完整路径名共享.o 目标文件
存档中包含多个.o 文件
用 ar 命令创建存档
最后编译其他程序
Head First 健身房全球化战略
计算卡路里
事情可没那么简单……
程序由碎片组成……
在运行时动态链接
.a 能在运行时链接吗?
首先,创建目标文件
一种平台一个叫法
C 语言工具箱
C 语言实验室 2
OpenCV
试想一下,当你出门在外,你的计算机能帮你看家,还能让你看到小偷的真面目。在这个实验中,你将借助 OpenCV 的神奇力量,创建一个基于 C 语言的入侵者检测器。
9 进程与系统调用
打破疆界
打破常规。
你已经学会了通过在命令行连接小工具的方式建立复杂的程序。但如果你想在代码中使用其他程序怎么办?本章中你将学会如何用系统服务来创建和控制进程,让程序发电子邮件、上网和使用任何已经安装过的程序。本章的最后,你将得到超越 C 语言的力量。
操作系统热线电话
黑客入侵了……
岂止是安全问题
exec() 给你更多控制权
exec() 函数有很多
数组函数:execv() 、execvp() 、execve()
传递环境变量
大多数系统调用以相同方式出错
用 RSS 读新闻
exec() 是程序中最后一行代码
用 fork()+exec() 运行子进程
C 语言工具箱
10 进程间通信
沟通的艺术
创建进程只是个开始。
如果你想控制运行中的进程,向进程发送数据或读取它的输出,该怎么办?通过进程间通信,进程可以合力完成某件工作。我们将向你展示如何让程序与系统中其他程序通信,从而提升它的战斗力。
输入输出重定向
进程内部一瞥
重定向即替换数据流
fileno() 返回描述符号
有时需要等待……
家书抵万金
用管道连接进程
案例研究:在浏览器中打开新闻
子进程
父进程
在浏览器中打开网页
进程之死
捕捉信号然后运行自己的代码
用 sigaction() 来注册 sigaction
使用信号处理器
用 kill 发送信号
打电话叫程序起床
C 语言工具箱
11 网络与套接字
金窝,银窝,不如 127.0.0.1 的草窝
不同计算机上的程序需要对话。
你已经学习了怎么用 I/O 与文件通信,还学习了如何让同一台计算机上的两个进程通信,现在你将走向世界舞台,让 C 程序通过互联网和世界各地的其他程序通信。本章的最后你将创建具有服务器和客户端功能的程序。
互联网 knock-knock 服务器
knock-knock 服务器概述
BLAB:服务器连接网络四部曲
套接字不是传统意义上的数据流
服务器有时不能正常启动
妈妈说要检查错误
从客户端读取数据
一次只能服务一个人
为每个客户端 fork() 一个子进程
自己动手写网络客户端
主动权在客户端手中
创建 IP 地址套接字
getaddrinfo() 获取域名的地址
C 语言工具箱
12 线程
平行世界
程序经常需要同时做几件事。
POSIX 线程可以派生几段并行执行的代码,从而提高代码的响应速度。但是要小心!线程虽然很强大,但它们之间可能发生冲突。本章你将学习如何用红绿灯来防止代码发生车祸。最终你将学会创建 POSIX 线程,并使用同步机制来保护共享数据的安全。
任务是串行的……还是……
……进程不是唯一答案
普通进程一次只做一件事
多雇几名员工:使用线程
如何创建线程?
用 pthread_create 创建线程
线程不安全
增设红绿灯
用互斥锁来管理交通
C 语言工具箱
C 语言实验室 3
爆破彗星
在本实验中,你将向史上最受欢迎、最长寿的电子游戏——《爆破彗星》——致敬!
i 饭后甜点
十大遗漏知识点
革命尚未成功,同志还需努力。
我们认为你还需要知道一些事,如果不讲,总觉得哪里不对劲,但我们又不希望这本书重得只有大力士才提得动,所以我们只做简单介绍。在你放下这本书前,尽情地享用这些“美味佳肴”吧。
#1. 运算符
#2. 预处理指令
#3. static 关键字
#4. 数据类型的大小
#5. 自动化测试
#6. 再谈 gcc
#7. 再谈 make
#8. 开发工具
#9. 创建 GUI
#10. 参考资料
ii 话题汇总
总复习
将 C 语言的特性尽收眼底。
我们把本书中出现过的所有关于 C 语言的话题和原理都汇总在了这里。把它们过一遍,看你还记得多少。每条话题都标明了来源章节号。如果你想不起来,很容易就能找到原文,甚至还可以把它们剪下来贴在墙上。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论