首页>参考读物>计算机科学与技术>软件与程序设计

C语言学习指南:从规范编程到专业级开发
作者 : [美]杰夫·苏哈伊(Jeff Szuhay) 著
译者 : 爱飞翔 译
丛书名 : 华章程序员书库
出版日期 : 2022-06-21
ISBN : 978-7-111-70602-1
定价 : 149.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 544
开本 : 16
原书名 : Learn C Programming
原出版社: Packt Publishing Ltd.
属性分类: 店面
包含CD : 无CD
绝版 : 未绝版
图书简介

本书将C语言中的知识由浅入深地安排成五个部分进行讲解,通过大量简明易懂的范例来演示C语言中的概念。第1部分介绍与C语言的语法及程序结构有关的基础概念。第2部分介绍C语言的数据类型。第3部分讲解如何用各种方式分配及释放内存。第4部分介绍与读取数据(输入数据)及写入数据(输出数据)有关的各种话题。第5部分详细解释如何创建并管理含有多份文件的程序项目。

图书特色

图书前言

学习编程就是学习如何用计算机解决问题。这是一个漫长而艰难的过程,充满了波折,但同时也会带来各种回报。刚开始学的时候,如果能编写程序并得出正确的结果,那么你会觉得小有收获;在继续学习的过程中,如果你发现自己竟然能解决以前不敢想象的大问题,那么你会觉得收获颇丰。
学习编程首先要从学习一门编程语言开始。本书想做的主要就是帮大家学会C语言。学习一门编程语言首先要学习它的语法,必须记住重要的关键字、标点以及基本的程序结构,并理解它们的含义。
本书所用的教学方式是告诉你一套工具、方法及操作手段,尽量降低你在学习过程中所遇问题的难度。书里的每个程序都是完整的,而且是采用新式的 C 语言语法编写的,同时笔者还会告诉你这个程序应该输出什么样的结果。
学习编程还有一个特殊的困难,即其中的变数太多。这里所说的“变数太多”意指编程的每个方面都会随时发生变化,而且以后会持续改变。计算机的硬件与操作系统会根据新的用法与需求而演进,计算机的编程语言也会演进,它需要克服旧版的缺陷,并提供新的特性,以解决新的问题。编程语言的用法会随着编程语言本身而发生改变。我们想把计算机放在不同的场景中使用,于是就必须让计算机能够解决新场景中的新问题。最后,使用计算机与计算机编程语言的用户及开发者自然也会变。编程语言的用法改变会让开发者用新的方式思考问题,而问题与问题的解法发生变化则会促使我们考虑可否进一步扩大编程语言的适用范围,这又推动了编程语言的下一轮发展。这个循环会一直持续下去。
C语言最早是由 Dennis Ritchie(丹尼斯·里奇,1941—2011)在20世纪70年代初开发的,但目前的C语言跟那时相比已经发生了很大变化。刚开始,C是一个特别简单但功能特别强大的语言,用来开发贝尔实验室的早期UNIX操作系统。那种C语言不是给初学编程的人使用的,它要求开发者必须先掌握高深的知识与编程技巧,然后才能用C写出健壮而稳定的程序。后来,C语言的编译器变得越来越普及,而设计编译器的人也花了很大功夫来限制那些有可能引发危险的语言特性。第一个符合 ANSI 标准的C语言(即ANSI C)是在 1989 年确定的。这个版本在 1999 年做了大幅修订,修订后的C语言叫作 C99,它添加了一些重要的特性,并澄清了C语言中的许多行为。后来,C语言又经过两次修订,这两次所得到的版本分别叫作C11和C18,它们都在前一版的基础上增加了少量内容,并修正了语言内部的一些问题。
目前的C语言要比早期版本更规范、更复杂,但与早期版本一样,它仍然是一门强大、高效,而且适用范围很广的语言。本书努力采用C99、C11与C18规范所定义的语法和概念来讲授C语言,并确保其中的每个程序都能在C11规范下编译并运行。以后,C18规范肯定会比现在更加流行,笔者希望,到时我们能用C18规范来顺利地编译并运行书中的程序。
就算不考虑刚才说的那些变数,我们也必须不断学习。读完本书之后,你应该能确定自己使用 C 语言的方式,在用C语言解决了许多问题之后,你又会发现新的东西,也就是说,你会发现,自己原来并不知道,C语言还有这样一些特性、用法以及局限。学编程实际上学的不单是编程本身,而是学习如何通过编写程序去解决问题,因此,这是一个“学习如何学习”的过程。
在阅读本书的过程中,你还会懂得一些跟C语言没有直接关系的编程概念,笔者会讲解一套通用的开发流程,而且会编写一款纸牌程序来演示如何运用这套流程。你可能对纸牌程序不感兴趣,但你应该关注的重点是这款程序是用怎样的一套流程来开发的。笔者在运用这套开发流程的时候会展示基本的实验与验证手法。
读者对象
笔者构思本书时,是想写给两类人看,一类是没学过任何编程语言的新手,另一类是虽然用过其他编程语言,但并没有接触过C语言的开发者。这两种人的需求差别很大。
对于纯粹的编程新手来说,笔者需要为他们详细讲解C语言的一些重要概念和编程方式,帮助他们成为熟练的 C 语言开发者。为此,笔者会细化每个概念,并通过实际的程序来演示。编程新手只需要熟悉计算机的基本操作就可以直接阅读本书,不需要提前具备其他专业知识。
对于用过其他编程语言的人来说,笔者想要在本书中完整展示C语言的语法以及一些常见的编程习惯。如果你是这类读者,那么只需要略读一下笔者解释概念的那部分内容,你应该把重点放在源代码上面。
无论你是哪类读者,都可以通过本书展示的这80多款程序,了解C语言的语法与编程风格—这种编程风格以及其中所采用的编程习惯在C语言中很常见,但在其他语言中则不一定会遇见。笔者会把在近40年的编程工作中所积累的实践经验,详细分享给大家。
本书内容
第一部分主要介绍与C语言的语法及程序结构有关的基础概念。
第1章介绍程序的开发流程,以及本书后续章节所要用到的工具。我们会用这些工具来建立、构建并运行第一个C语言程序,也就是“Hello, world!”程序。笔者还会介绍怎样给代码添加注释,以及如何用代码做实验。
第2章介绍语句和块,还会解释函数定义、函数声明以及函数原型的概念。笔者会演示如何调用函数,并告诉大家函数执行的顺序。语句、块与函数决定了 C 程序的结构。
第3章解释C语言如何运用数据类型,以各种方式来表示值。每种数据类型都有大小与取值范围,C 语言会据此解读某个值的含义。
第4章介绍变量与常量,这两种量都用来容纳值。要想让变量具备某个值,我们必须给它赋值,笔者会介绍各种赋值方式。
第5章介绍运算,笔者会告诉大家与各种数据类型有关的运算,以及如何通过这样的运算来操作该类型的值。
第6章介绍流程控制语句,该语句会根据某个表达式的结果来决定是执行其中一组语句,还是执行另一组语句。
第7章介绍各种循环语句。笔者还会演示怎样正确使用goto,以及怎样避免滥用goto。另外,笔者还会介绍一些其他的控制循环与迭代的方法。
第8章解释命名常量与枚举,并说明它们的用法。
第二部分针对第一部分所讲的基础(或固有)数据类型进行扩展延伸,帮助大家理解更复杂的数据类型。
第9章讲解怎样用一组变量来制作结构体(structure),以表示复杂的对象。笔者会介绍可以在结构体上执行的操作,以及结构体与面向对象编程(Object-Oriented Programming,OOP)之间的关系。
第10章介绍如何给enum与struct关键字所声明出的枚举及结构体重命名,还会讲解编译器的选项及头文件。
第11章演示如何定义、初始化并访问简单的数组。笔者会讲解怎样使用循环遍历数组,还会演示如何通过函数来操作数组。
第12章会把数组从一维(也叫单维)推广到二维、三维乃至任意维度。笔者会演示如何用循环与函数来声明、初始化并访问这样的多维数组。
第13章介绍直接寻址和通过指针间接寻址这两种寻址方式之间的区别。笔者会告诉大家如何理解“指针”这一概念,还会演示怎样在函数中使用指针,以及怎样使用指向结构体的指针。
第14章讲解指针与数组之间的相似之处与区别。
第15章介绍ASCII字符集与C字符串。C 字符串是一种带有两项特殊属性的数组。我们会开发一款程序,把 ASCII 字符集用表格的形式打印出来。笔者还会介绍 C 语言标准库中与字符串有关的操作。
第16章在结构体与数组等概念的基础上创建各种复杂的数据结构并综合运用。笔者会开发一款完整的扑克程序,并在此过程中演示每一种复杂的结构体。大家可以通过本章相当透彻地了解什么叫作有步骤的迭代式程序开发。
第三部分讲解如何用各种方式分配及释放(也叫解除分配)内存。
第17章介绍自动存储类与动态存储类的概念及区别,还对比了内部存储类与外部存储类这两种存储方式。笔者会演示如何用static关键字声明静态变量。
第18章介绍如何进行动态内存分配,以及如何对这样分配的内存执行各种操作。笔者会演示一款动态链表程序,还会介绍其他一些动态分配的结构体。
第四部分介绍与读取数据(也就是输入数据)及写入数据(也就是输出数据)有关的各种话题。
第19章详细介绍printf()函数的各种格式说明符,笔者会讲解与每一种固有的数据类型相对应的说明符,包括带符号的整数、不带符号的整数、单精度浮点数、双精度浮点数、字符串以及字符。
第20章演示怎样利用main()函数的argc与argv参数,来获取用户在执行本程序时通过命令行界面所输入的内容。
第21章演示如何用scanf()函数读取输入流中的值。笔者会告诉大家,printf()与scanf()所使用的格式说明符虽然相似,但实际上有很大区别。我们还会谈到内部数据转换以及无格式的(或者说,未经格式化的)输入与输出。
第22章主要谈概念。笔者会讲解文件的基本概念,并演示怎样在程序中开启和关闭文件,以及如何让用户通过命令行界面来指定有待操作的文件名。
第23章演示怎样通过getopt()函数获取用户在命令行界面所指定的各种选项(也叫开关)。笔者会扩充早前的范例程序,让它能够读取输入文件中所包含的名字,并通过链表给这些名字排序,然后将排序结果写入文件。
第五部分详细解释如何创建并管理含有多个文件的程序项目(即多文件的程序)。
第24章以第16章中创建的程序作示例,告诉大家怎样把程序代码合理地拆分到多个源文件中,让每个源文件所包含的函数都跟该文件所要操作的结构体相符。笔者还会介绍怎样高效而安全地使用预处理器。
第25章从不同的方面讲解作用域这一概念,并解释其与单文件的程序和多文件的程序有何关系。笔者会详细描述变量的作用域及函数的作用域。最后,笔者会提出一些建议,告诉大家在看完本书之后,如何继续学习 C 语言乃至一般的程序开发知识。
附录中包含许多参考资料,即C语言关键字、运算符优先级、某些常用GCC与CLang 选项、ASCII 字符集、Bstrlib库用法、Unicode 概论以及对C语言标准库中各头文件所做的介绍。
怎样充分利用这书
为了学习书中的内容,你需要准备一款简单的文本编辑器、一个终端机或控制台程序,以及一款编译器。笔者会在第1章描述这三样工具,并告诉你如何下载与使用它们。下面的表格列出了本书对编程工具所做的技术要求。
操作系统 费用 下载网址
Linux/UNIX
文本编辑器(选择下列四种之一)
Nano 免费  https://www.nano-editor.org/download.php
Vim或vi <操作系统内置>  N/A
GEdit <操作系统内置>  https://wiki.gnome.org/Apps/Gedit
Emacs 免费  https://www.gnu.org/software/emacs/download.html
编译器  (安装方式依照具体的 Linux/UNIX版本来定)
GCC <操作系统内置>  https://gcc.gnu.org/install/(请参考表格后面的说明,以了解如何在某些 Linux 系统里面安装 GCC)
终端
Terminal <操作系统内置>  N/A
macOS
文本编辑器(选择下列三种之一)
Vim或vi <操作系统内置>  N/A
emacs 免费  https://www.gnu.org/software/emacs/download.html
Bbedit 免费  https://www.barebones.com/products/bbedit/
编译器
Clang <操作系统内置>
终端
terminal.app <操作系统内置>  N/A
Windows
文本编辑器(选择下列三种之一)
Notepad(记事本) <操作系统内置>  N/A
Notepad++ 免费  https://notepad-plus-plus.org/downloads/
emacs 免费  https://www.gnu.org/software/emacs/download.html
编译器
Cygwin 免费  http://www.cygwin.com
MinGW 免费  http://mingw-w64.org
终端
Console <操作系统内置>  N/A

要想在Linux操作系统中安装GCC,你需要执行这样的命令:
如果你使用的是基于 RPM 的 Linux 系统,例如 RedHat、Fedora或CentOS等,那么请打开 Terminal 窗口(终端窗口或终端机窗口),并执行下列命令:

如果你使用的是 Debian Linux,那么请打开Terminal窗口,并执行下列命令:

为了判断自己是否正确安装了GCC或Clang,请在Terminal窗口中执行下列命令:

无论你看的是本书电子版还是纸质版,笔者都建议你亲手把代码敲一遍。手工输入完代码之后,你再去跟GitHub网站上面的代码库进行对比(稍后会给出本书的代码库地址)。这样做可以减少因复制和粘贴而引发的代码错误。
如果你是编程新手,那么准备好开发工具之后,还必须了解如何阅读编程方面的书籍。在读此类书籍时,你应该采用如下方法:
1.通读全章,大致了解本章所要展示的概念。
2.将本章再读一遍,这次阅读时,每遇到一个程序,就把该程序的代码打出来,然后运行,以确保自己所看到的结果跟书中讲的相同。如果没有得到应有的结果,那就试着弄清楚自己的程序跟书中的程序有什么区别(找到区别之后,修改程序让它得出与本书相符的结果)。编程与数学类似,都必须做练习,只有这样才能学会编程。只观察代码是学不会编程的,你必须亲自编写代码才行。
3.用心记住本章所提到的关键字和语法。这可以大幅提升学习速度。
4.精准地思考。编程语言对语法要求相当严格,这是尤其需要注意的。你必须仔细地考虑问题,有时为了解决某个问题,你需要费尽心思才能想出正确的步骤。
5.将本章提到的概念与范例程序复习一遍,把不懂的地方记下来。
如果你以前用过别的编程语言,那么在初学 C 语言时笔者还是强烈建议你能够先把每章的正文和其中的范例程序略读一遍。然后,再把程序代码录入自己的计算机,并确保程序的运行结果正确无误。这样能够帮助你迅速掌握 C 语言的语法及编程习惯。
在阅读编程方面的书籍时,你必须先了解所读的书属于哪一类,只有这样,你才能用最合适的办法来阅读。我们见到的计算机编程书籍一般有以下几类:
概念书(讲述编程概念的书籍):这一类书籍会从底层概念与设计理念的角度来讲述。Kernighan 与 Ritchie 所写的The C Programming Language(《C 程序设计语言》)就属于此类。
教科书(教材):这一类书籍通常会把编程语言的每个主要方面都讲到,有时还会讲解得极其详细,而且通常包含许多代码片段。Paul Deitel与Harvey Deitel写的书,以及K. N. King写的C Programming: A Modern Approach(《C语言程序设计:现代方法》)就属于此类。这些书籍通常用在正式的编程课中。
参考书:这一类书籍会详细描述语法规则。Harbison与Steele写的C: A Reference Manual(《C 语言参考手册》)就属于此类。
“菜谱书”(教程):这一类书籍会给出具体的解决方案,告诉你怎样用某种语言来解决某些问题。Perry 写的Advanced C Programming by Example、Van Der Linden 写的Expert C Programming: Deep Secrets(《C 专家编程》)以及Sedgewick写的Algorithms in C(《算法:C 语言实现》)就属于此类。
专题书:这一类书籍深入研究编程语言的某个或某些方面。Reek 写的Pointers in C(《C和指针》)就属于此类。
实践书:这一类书籍会告诉你怎样用某种语言(例如 C 语言)解决一般的编程问题。Hanson 写的C Interfaces and Implementations(《C 语言接口与实现》)与 Klemens 写的21st Century C: C Tips from the New School(《C 程序设计新思维》)就属于此类。
每一类书籍的读法都不同。比方说,概念书可能只读一遍就好,但参考书则应该放在手边反复翻阅,另外你可能还得准备一些教程(即“菜谱书”)用来解决有可能遇到的某些问题。
笔者希望本书能够同时具备C语言“菜谱书”、参考书与实践书的功能。说它是菜谱书,是因为书中提供的程序代码都是能够运行的代码,你可以根据运行结果,判断你所采用的 C 语言编译器在当前使用的操作系统上所表现出的行为。说它是参考书,是因为书中提供了足够多的 C 语言知识,让你能够把它作为初次接触C语言时的参考资料。说它是实践书,是因为笔者想要在书中给大家演示编写 C 语言代码的最佳方式。
笔者还希望你在阅读完本书之后,能够继续阅读其他书籍。在甄选后续的书籍时,至少应该选择针对 C99 标准而写的书,如果用的是 C11 或 C18 标准,那就更好了。早于 C99 标准的代码基本上都是旧式的代码,从C99开始,我们有了更加高效的 C 语言编程方式。
下载示例代码及图像
本书的代码包也托管在GitHub上,地址为:https://github.com/PacktPubli-shing/Learn-C-Programming。如果代码有更新,笔者会把新版代码放在GitHub 代码仓库中。
你也可以访问https://github.com/PacktPublishing/查看其他代码包,那里还有丰富的图书与视频资源。
书中的截屏与图表可以在https://static.packt-cdn.com/downloads/9781789349917_ ColorImages.pdf下载。
本书约定
下面是本书的排版约定。
CodeInText(代码体):文本中的代码、数据库表名、文件夹名/目录名、文件名、文件扩展名、路径名、举例时所用的 URL、用户输入的内容,以及 Twitter 账号名,都印刷成代码体。例如:“友情提示,这个需要匹配的地方涉及int main()与return 0;这两行代码”。
整块的代码,印刷成下面这样:

如果笔者要强调某块代码中的某一部分,那么相应的代码行或代码项会印刷成粗体:

需要在命令行界面输入的命令,或者命令所输出的内容,则会以如下形式印刷:

Bold(粗体):表示某个新术语或重要词汇,以及屏幕上的关键文字。比方说,菜单或对话框中的文字就会印刷成粗体。例如:“这是个有用的程序,因为它会把一些东西输出到 Terminal(终端/终端机),也就是consoe(控制台)”。
警示信息或者重要的评注信息。
提示与技巧。

上架指导

计算机\程序设计

封底文字

C语言是一门功能强大的通用编程语言,很适合刚接触编程的人学习。本书会告诉你如何用C语言编写计算机程序并开发软件。有经验的程序员也可以通过本书来熟悉C语言。
本书会讲解基本的编程概念并演示如何在C语言中运用这些概念。在阅读本书的过程中,你会看到如何利用这些概念来组织程序的结构,并编写出可以运行的C程序。书中的范例会演示函数、数据类型以及条件语句的用法,也会演示循环、迭代、数组、指针与字符串的用法。这些范例会让你逐渐了解如何在代码中添加注释、如何测试程序并验证程序的结果是否正确、如何使用基本的输入与输出机制,以及如何编写完整的应用程序。
读完本书,你将掌握基本的C语言编程技能。你可以把这些知识运用到其他编程语言中,并以此为基础,继续提升自己的编程水平。

学完本书,你将
掌握基本的编程概念,并学习用C语言来实现这些概念。
编写可运行、清晰易懂的程序。
在已经写好的程序上故意制造问题,并学习如何调试有问题的代码。
养成良好的编程习惯,厘清编程思路。
了解与大型项目有关的通用编程理念。
学习如何使用构建块搭建复杂且功能丰富的大型程序。
学习使用C语言标准库中的函数来编写程序,并了解这样做的好处。

译者序

记得当年学C语言的时候,自己跟许多人一样,看的都是比较传统的教程,例如Brian W. Kernighan与Dennis M. Ritchie 的The C Programming Language(中文版《C程序设计语言》,简称K&R C)、Stephen Prata的C Primer Plus,以及谭浩强先生的《C程序设计,第2版》。现在虽然有了多种流行的编程语言,但 C 语言依然是一门经典的语言,而且比原来更加成熟、更加规范。
初学编程的人可能担心代码太过高深,总喜欢从简单且直观的编程语言及范例入手,这当然没错,然而在初步掌握程序的运作原理与开发流程之后,应该适当地学习操作系统与硬件方面的知识,以帮助自己写出既清晰易懂,又能充分发挥计算机优势的代码。在提升开发水平的过程中,C 语言正扮演着这样一个关键的角色,它具备丰富的程序库与函数,同时也提供了指针等底层机制,让开发者能够灵活地操作内存数据,以实现许多本来需要用原始的汇编指令才能完成的功能。
怎样让初学者(尤其是连一门编程语言都没接触过的人)了解像C语言这样广阔而高深的语言一直是个难题。本书作者Jeff Szuhay尝试把C语言中的知识由浅入深地安排成5个部分,并在每一部分的各个章节中,通过大量简明易懂的范例来演示 C 语言中的概念,然后将其推广到大型的开发项目、其他的编程语言乃至一般的软件开发工作中。他还根据多年的开发经验在书中提出了一些建议,帮助读者养成良好的编程习惯与清晰的编程思路,继而选定接下来的学习方向。
希望本书可以让大家顺利掌握C语言的基础知识,并在此之上有所提高。在翻译过程中,译者尽量遵循原文并加以注释。为了让文字更为流畅,译者还根据语境及汉语习惯,补充了原文所省略的部分。
翻译本书的过程中,我得到了机械工业出版社华章分社各位朋友的帮助,在此深表谢意,尤其感谢关敏与李忠明两位编辑给我提供建议。同时,感谢友人小河支持并鼓励我做好翻译工作。
由于本书篇幅较长,而译者水平有限,错误与疏漏在所难免。请大家访问github.com/jeffreybaoshenlee/lcp-errata/issues留言,或发邮件至eastarstormlee@gmail.com与我进行交流。

爱飞翔
2021年7月22日

图书目录

译者序
前言
作者简介
审校者简介
第一部分 C语言的基础知识
第1章 运行Hello, World!程序2
1.1 技术要求2
1.2 编写第一个C语言程序3
1.3 了解程序开发流程4
1.3.1 编辑5
1.3.2 编译6
1.3.3 运行9
1.3.4 验证10
1.3.5 重复10
1.4 创建、录入并保存第一个C语言程序12
1.5 编译第一个C语言程序13
1.6 运行第一个C语言程序14
1.7 添加注释14
1.7.1 怎样写好注释15
1.7.2 给Hello, world!程序添加注释17
1.8 学着在代码上做实验18
1.9 小结19
第2章 了解程序的结构21
2.1 技术要求21
2.2 语句与代码块22
2.2.1 在语句与代码块中试验各种转义序列23
2.2.2 了解分隔符的用法25
2.2.3 了解空白的用法27
2.2.4 了解C语言的各种语句30
2.3 了解C语言的函数32
2.4 了解如何定义函数32
2.4.1 了解函数的标识符33
2.4.2 了解函数的语句块35
2.4.3 了解函数的返回值35
2.4.4 通过函数的参数传递数值37
2.5 执行顺序42
2.6 了解如何声明函数43
2.7 小结46
第3章 基本的数据类型47
3.1 技术要求47
3.2 了解数据类型48
3.3 字节与数据块51
3.4 如何在C语言代码中表示整数52
3.4.1 如何在C语言代码中表示正整数与负整数53
3.4.2 如何在C语言代码中采用大小不同的数据块来表示整数53
3.5 如何在C语言中表示小数55
3.6 如何在C语言中表示单个字符55
3.7 如何在C语言中表示布尔值56
3.8 如何在C语言中查询各种数据类型的大小57
3.8.1 sizeof()运算符57
3.8.2 各种数据类型的取值范围59
3.9 小结60
第4章 使用变量并为变量赋值61
4.1 技术要求62
4.2 选用合适的类型来表示数据值62
4.3 学习变量的用法62
4.3.1 给变量命名63
4.3.2 显式地指定变量类型64
4.3.3 显式地指定变量类型并初始化65
4.4 学习常量的用法66
4.4.1 字面常量66
4.4.2 用预处理指令定义常量值68
4.4.3 显式地定义某种类型的常量69
4.4.4 给常量命名69
4.5 把类型适当的值赋给变量70
4.5.1 通过赋值语句显式地赋值71
4.5.2 通过给函数传递参数来赋值71
4.5.3 通过return语句来赋值73
4.6 小结74
第5章 运算符与表达式75
5.1 技术要求76
5.2 表达式与运算符76
5.3 在数字值上执行运算78
5.4 类型转换83
5.4.1 隐式类型转换83
5.4.2 显式类型转换87
5.5 字符型数据支持的操作88
5.6 逻辑运算符与关系运算符89
5.7 位运算符92
5.8 条件运算符94
5.9 序列运算符95
5.10 复合赋值运算符96
5.11 在一条表达式中给多个变量赋值97
5.12 增量运算符97
5.13 运算符之间的优先次序以及括号的用法99
5.14 小结100
第6章 用条件语句控制程序流102
6.1 技术要求103
6.2 了解各种条件表达式103
6.3 if() ... else ...语句104
6.4 switch() ...语句107
6.5 多个if() ... else ...语句111
6.6 嵌套的if() ... else ...语句114
6.7 小结117
第7章 循环与迭代119
7.1 技术要求119
7.2 重复执行代码120
7.3 蛮力法实现重复执行代码122
7.4 while () ...循环语句124
7.5 for() ...循环语句127
7.6 do ... while()循环语句129
7.7 如何把一种循环改写成另一种循环131
7.8 善用goto语句以实现无条件跳转132
7.9 用break与continue语句来控制循环136
7.10 无限循环139
7.11 小结140
第8章 创建并使用枚举值141
8.1 技术要求141
8.2 枚举值142
8.2.1 定义枚举类型与枚举值143
8.2.2 使用枚举值145
8.3 用switch()...语句判断枚举变量的取值148
8.4 小结152
第二部分 复杂的数据类型
第9章 创建并使用结构体154
9.1 技术要求155
9.2 结构体155
9.2.1 声明结构体156
9.2.2 初始化结构体并访问其中的字段160
9.3 用函数操作结构体161
9.4 包含其他结构体的结构体163
9.4.1 用函数初始化结构体165
9.4.2 复用某个函数以打印大结构体中的多个小结构体166
9.5 从结构体入手理解面向对象编程169
9.6 小结170
第10章 用typedef创建自定义数据类型171
10.1 技术要求171
10.2 用typedef给固有类型起别名172
10.3 用typedef简化枚举类型的用法174
10.4 用typedef简化结构体类型的用法176
10.5 typedef的其他用法179
10.6 几个有用的编译器选项179
10.7 把自定义类型及typedef说明符放在头文件中180
10.8 小结183
第11章 数组185
11.1 技术要求185
11.2 声明并初始化数组186
11.3 访问数组中的元素189
11.4 通过循环来操作数组192
11.5 使用函数来操作数组193
11.6 小结196
第12章 多维数组198
12.1 技术要求198
12.2 从一维数组到多维数组199
12.2.1 重新审视一维数组199
12.2.2 由一维数组来理解二维数组200
12.2.3 由二维数组来理解三维数组201
12.2.4 理解N维数组203
12.3 声明并初始化多维数组203
12.3.1 声明二维数组204
12.3.2 初始化二维数组204
12.3.3 声明三维数组204
12.3.4 初始化三维数组205
12.3.5 声明并初始化N维数组205
12.4 访问多维数组中的元素206
12.5 用多层循环操作多维数组207
12.5.1 用二层的嵌套循环遍历二维数组208
12.5.2 用三层的嵌套循环遍历三维数组208
12.6 在函数中使用多维数组209
12.7 小结212
第13章 指针213
13.1 技术要求214
13.2 C语言中的难点:指针214
13.3 指针的基础知识215
13.3.1 直接寻址与间接寻址216
13.3.2 内存与内存寻址216
13.3.3 管理并访问内存217
13.3.4 用现实示例来类比指针218
13.4 指针型变量的声明、命名及赋值220
13.4.1 声明指针型变量220
13.4.2 命名指针型变量221
13.4.3 给指针赋值(让指针指向某个地址)222
13.5 与指针有关的操作222
13.5.1 给指针赋值222
13.5.2 NULL指针与void*指针223
13.5.3 访问指针的目标225
13.5.4 指针算术228
13.5.5 比较指针228
13.6 表述指针的操作230
13.7 可变函数参数231
13.7.1 按引用传递233
13.7.2 直接把地址传给函数,而不通过指针变量235
13.7.3 指向指针的指针236
13.8 指向结构体的指针238
13.8.1 通过指针访问结构体及其字段239
13.8.2 在函数中使用指向结构体的指针239
13.9 小结241
第14章 数组与指针242
14.1 技术要求242
14.2 数组名称与指针之间的关系242
14.3 数组元素与指针之间的关系245
14.4 通过指针操作数组246
14.4.1 在指针上执行算术运算246
14.4.2 对指针使用自增运算符247
14.4.3 将数组作为重新访问的函数指针传递250
14.4.4 数组名称与指向该数组的指针有时可以互换251
14.5 指向数组的指针数组253
14.6 小结259
第15章 字符串260
15.1 技术要求261
15.2 字符串的基本单元:字符261
15.2.1 char类型与ASCII字符集262
15.2.2 比ASCII更大的字符集:UTF-8及Unicode265
15.2.3 字符支持的操作266
15.2.4 判断字符是否具备某项特征268
15.2.5 操作字符270
15.3 C语言字符串275
15.3.1 带有终结符的字符数组275
15.3.2 C语言字符串的优点276
15.3.3 C语言字符串的缺点276
15.4 声明并初始化字符串277
15.4.1 声明字符串277
15.4.2 初始化字符串278
15.4.3 把字符串传给函数280
15.4.4 空白字符串与空字符串281
15.4.5 重新审视Hello, World!程序282
15.5 创建并使用字符串数组283
15.6 用标准库中的函数执行常见的字符串操作288
15.6.1 常用的字符串函数288
15.6.2 更安全的字符串函数289
15.7 小结291
第16章 创建并使用复杂的结构体293
16.1 技术要求294
16.2 为什么需要复杂的结构体294
16.3 重新审视card4.c295
16.4 理解结构体数组302
16.4.1 创建结构体数组302
16.4.2 访问数组中的结构体元素303
16.4.3 操作结构体数组305
16.5 包含小结构体的大结构体310
16.5.1 创建包含小结构体的大结构体310
16.5.2 访问大结构体中的小结构体所具备的字段311
16.5.3 操作包含小结构体的大结构体312
16.6 使用含有数组的结构体319
16.6.1 了解随机与随机数生成器319
16.6.2 创建含有数组的结构体320
16.6.3 访问结构体所含数组中的元素321
16.6.4 操作结构体所含数组中的元素321
16.7 使用含有结构体数组的大结构体324
16.7.1 创建包含结构体数组的大结构体325
16.7.2 访问大结构体中的结构体数组内的各个小结构体325
16.7.3 操作包含结构体数组的大结构体326
16.7.4 写出最终版的carddeck.c文件327
16.8 小结333
第三部分 内存分配
第17章 理解内存分配与生命期336
17.1 技术要求336
17.2 定义C语言中的各种存储类337
17.3 固定存储类(主要是其中的自动存储类)与动态存储类337
17.3.1 固定存储类(主要是其中的自动存储类)338
17.3.2 动态存储类338
17.4 内部存储类与外部存储类338
17.4.1 内部(或局部)存储类339
17.4.2 外部(或全局)存储类340
17.4.3 自动变量(即存储类为auto的变量)所具备的生命期341
17.5 理解静态变量(即存储类为static的变量)341
17.5.1 函数内的静态变量341
17.5.2 函数外的静态变量343
17.5.3 静态变量的生命期344
17.6 小结344
第18章 动态内存分配345
18.1 技术要求345
18.2 了解动态内存346
18.3 分配并释放动态内存347
18.3.1 分配动态内存348
18.3.2 释放动态内存349
18.3.3 访问动态内存350
18.3.4 动态内存的生命期350
18.4 与动态内存分配有关的注意事项351
18.5 一种动态的数据结构:链表354
18.5.1 定义链表所需的各种结构体354
18.5.2 声明链表支持的操作355
18.5.3 更复杂的链表操作364
18.5.4 编写测试程序以验证链表实现得是否正确365
18.6 其他动态数据结构369
18.7 小结370
第四部分 输入与输出
第19章 学习各种输出格式372
19.1 技术要求373
19.2 重新审视printf()函数373
19.3 用格式说明符调整无符号整数的格式375
19.3.1 在各种进制下解读无符号整数375
19.3.2 把负数当成无符号整数来显示376
19.3.3 用各种进制表示2与9的整数次方377
19.3.4 打印指针的值377
19.4 用格式说明符调整带符号整数的格式379
19.4.1 使用字段宽度、精度、对齐方式与填充方式来显示带符号整数379
19.4.2 针对长长整数指定格式说明符380
19.4.3 用各种修饰符调整2与9的整数次方的显示效果380
19.5 用格式说明符调整浮点数的格式381
19.5.1 使用字段宽度、精度、对齐方式与填充方式来显示浮点数382
19.5.2 用十六进制显示浮点数383
19.5.3 用最合适的字段宽度显示浮点数383
19.6 用格式说明符调整字符串与字符的格式385
19.6.1 使用字段宽度、精度、对齐方式与填充方式来显示字符串385
19.6.2 输出子字符串386
19.6.3 调整单个字符的输出格式386
19.7 小结387
第20章 从命令行界面获取输入信息388
20.1 技术要求388
20.2 重新审视main()函数388
20.2.1 main()函数的特别之处389
20.2.2 main()函数的两种形式389
20.3 使用argc与argv参数390
20.3.1 演示argc与argv的简单用法390
20.3.2 命令行选项与命令行处理器392
20.4 小结395
第21章 调整输入值的格式397
21.1 技术要求398
21.2 流简介398
21.2.1 理解标准输出流400
21.2.2 理解标准输入流402
21.2.3 通过printf()与fprintf()重新审视控制台输出402
21.2.4 通过scanf()函数探索控制台输入403
21.3 用scanf()函数读取格式化的输入数据404
21.3.1 用scanf()函数读取用户输入的数字值404
21.3.2 用scanf()函数读取用户输入的字符串与字符408
21.3.3 用scan set限定用户输入的字符411
21.3.4 控制scanf()处理输入数据时所用的字段宽度413
21.4 通过字符串缓冲区转换数据416
21.4.1 通过sprintf()与sscanf()在值与字符串之间转换417
21.4.2 用atoi()与atod()将字符串转换成数字418
21.5 无格式的输入与输出419
21.5.1 从控制台输入字符串或把字符串输出到控制台419
21.5.2 通过gets()函数获取简单的输入字符串并通过puts()函数显示简单的输出字符串420
21.5.3 用fgets()与fputs()获取一系列名称并输出排序后的名单421
21.6 小结425
第22章 文件427
22.1 技术要求428
22.2 文件的基本概念428
22.2.1 重新审视文件流428
22.2.2 FILE流的各项属性429
22.2.3 开启和关闭文件430
22.2.4 了解每种数据流所支持的文件操作431
22.3 文件系统的基础知识432
22.4 打开文件以读取数据或写入数据434
22.4.1 在程序中获取用户输入的文件名436
22.4.2 获取用户通过命令行参数传入的文件名438
22.5 小结439
第23章 文件输入和文件输出440
23.1 技术要求440
23.2 处理文件441
23.3 创建一个未排序名称的文件446
23.3.1 从fgets()获取到的输入字符串中移除首尾的空白字符447
23.3.2 读取名称和写入名称448
23.4 读取未排序的人名并输出排序后的名单452
23.4.1 用链表给人名排序454
23.4.2 将排序后的名单写入输出端458
23.5 小结460
第五部分 开发大型程序
第24章 开发多文件的程序464
24.1 技术要求465
24.2 理解多文件的程序465
24.3 把声明写在头文件中,把定义写在源文件中466
24.3.1 创建源文件466
24.3.2 创建头文件467
24.4 重新审视预处理器469
24.4.1 了解预处理器的局限与风险469
24.4.2 如何有效地使用预处理器470
24.4.3 利用预处理器来调试程序471
24.5 创建多文件的程序474
24.5.1 把Card结构体与相关函数提取到相应的文件中475
24.5.2 把Hand结构体与相关函数提取到相应的文件中477
24.5.3 把Deck结构体与相关函数提取到相应的文件中479
24.5.4 完成整个dealer程序480
24.6 构建多文件的程序482
24.7 小结484
第25章 作用域485
25.1 技术要求486
25.2 从可见范围、存在范围及链接范围三方面来定义作用域486
25.2.1 可见范围486
25.2.2 存在范围487
25.2.3 链接范围488
25.2.4 综合考虑可见范围、存在范围与链接范围489
25.3 变量的作用域490
25.3.1 语句块级别的变量的作用域490
25.3.2 函数参数列表中的变量的作用域493
25.3.3 文件级别的变量的作用域493
25.3.4 全局变量494
25.4 函数的作用域495
25.4.1 作用域与信息隐藏495
25.4.2 用static关键字修饰函数496
25.5 小结500
25.6 结束语501
附录
附录A C语言的规范与关键字506
附录B 运算符优先级表格508
附录C GCC与Clang编译器的常用选项510
附录D ASCII字符集511
附录E 一个更好的字符串库:Bstrlib512
附录F Unicode与UTF-8517
附录G C语言标准库520

教学资源推荐
作者: [美]埃里克 S. 罗伯茨(Eric S. Roberts) 著
作者: (美)Victor Shtern
作者: [美] 凯·霍斯特曼(Cay Horstmann) 兰斯·尼塞斯(Rance Necaise) 著
作者: 周庆国 崔向平 郅朋 编著
参考读物推荐
作者: [美]帕维尔·约西福维奇(Pavel Yosifovich) 著
作者: (美)Scott Seely
作者: 唐盛彬 编著
作者: 邹均 于斌 庄鹏 邢春晓 等著