一起读经典《C Primer Plus(第6版)中文版》

​点击关注 异步图书,置顶公众号

每天与你分享 IT好书 技术干货 职场知识


参与文末话题讨论,每日赠送异步图书

——异步小编

今天我们要读的是一本经久不衰的C语言畅销经典教程,自1984年第一版诞生以来,它持续畅销了34年,升级了6个版本,是程序员们学习C语言不可多得的良师益友,它就是《C Primer Plus(第6版)中文版》。

 1.   C语言的历史和变革

提到C语言,就绕不开计算机编程语言的演变与进化。这足以证明C语言在整个编程领域举足轻重的地位。C语言不是凭空出现的,它的背后总是伴随着长长的故事,有时候都不知道从哪里开始讲起……

C语言的前身是B语言,而B语言的前身是BCPL语言,BCPL又源自CPL语言,CPL在Algol 60的基础上发展而来……那么,我们就从这里开始吧。

在高级编程语言的进化史中,不得不提ALGOL。1950年,欧美计算机学家合力开发了ALGOL。ALGOL是算法语言(ALGOrithmic Language)的简称,也是在计算机发展史上首批清晰定义的高级语言。国际计算机学会(Assocoation for Computing Machinery,简称ACM)将ALGOL模式列为算法描述的标准,启发了ALGOL类现代语言PascalAdaC等语言的出现。

 Algol 58

1958年,ACM与当时联邦德国的应用数学和力学协会(Gesellschaft für Angewandte Mathematik und Mechanik,简称GAMM)出席了在苏黎世举行的第一次程序设计会议,把新语言命名为IAL,即国际代数语言(International Algebraic Language,简称IAL),后定名为ALGOL,即算法语言。后来,又改为Algol 58,成为ALGOL家族的第一位成员。

 Algol 60

1960年1月,图灵奖获得者艾伦•佩利(Alan J.Perlis)在巴黎举行的顶级软件专家研讨会上,发表了“算法语言Algol 60报告”,确定了程序设计语言Algol 60。1962年,艾伦•佩利又对Algol 60进行了修正。

Algol 60引进了许多新的概念(如:局部性概念、动态、递归、巴科斯-诺尔范式BNF等等),是程序设计语言发展史上的一个里程碑。它标志着程序设计语言成为一门独立的科学学科,并为后来软件自动化及软件可靠性的发展奠定了基础。Algol 60是许多后来的程序设计语言必不可少的软件工程工具的原型,它的发展是一群极具天赋的人的工作成果。

  CPL(Combined Programming Language)

1963年,英国剑桥大学在Algol 60的基础上开发出了CPL语言。CPL语言更接近硬件一些,但规模比较大,难以实现。

 BCPL(Basic Combined Programming Language)

BCPL源自CPL语言。1967年,英国剑桥大学的马丁•理察德(Martin Richards)在访问麻省理工大学期间,对CPL语言进行了简化,移除了该语言中最复杂的部分,设计出了BCPL语言。该语言在70年代早期广泛应用于很多项目中,是最早被用做牛津大学OS6操作系统中的开发工具。后来,经过美国贝尔实验室的改进和推广,成为了UNIX上的常用开发语言。

BCPL有些类似于Fortran,也是典型的面向过程的高级语言。BCPL也是最早使用库函数封装基本输入输出的语言之一,所以它的跨平台移植性很好。与同时代的BASICPASCAL不同,BCPL的代码用小写字母书写。早期BCPL的内存管理很糟糕,不过后来得到了改善。但是,BCPL对字符串的支持很差,这个缺点一直没有解决。

作为早期的编程语言,BCPL如今已不再广泛使用,但它的影响却是深远的。BCPL程序从一个主函数中开始,可以在各个函数中添加功能模块,函数支持嵌套和递归。BCPL是第一个使用括号的语言(如今,括号在各种编程语言中都随处可见)。

  B语言

1970年,美国贝尔实验室的研究员肯•汤普森(Ken Thompson)自己编写了一个模拟在太阳系航行的电子游戏:Space Travel。他找到一台没有操作系统的空闲机器PDP-7,而游戏必须使用操作系统的一些功能,于是他着手为PDP-7开发操作系统。但是,用现有的语言在这台机器上开发操作系统,困难重重。汤普森删减了BCPL语言其中的非必备组件,开发出了一种通用的程序设计语言:B语言(取BCPL的第一个字母),并用B语言写出了第一个UNIX操作系统。

B语言是一种无类型语言,所有的数据都和机器字相对应。B语言非常简单,而且更接近硬件,程序员可以直接通过内存地址操作内存。B语言除包含一些库函数外,还包含了汤普森的一些个人偏好(主要在一些特定的程序中减少非空格字符的数量)。虽然B语言的使用时间不长,但是它在编程语言发展历史上起到了承前启后的重要作用。

​图1  DEC的PDP-7

图1 DEC的PDP-7

  C语言

好景不长,B语言的无类型特性成为在PDP-11机器上访问字符类型的软肋。1971年,同样酷爱Space Travel的丹尼斯•里奇(Dennis M.Ritchie)为了能早点儿玩上游戏,加入了汤普森的开发项目,合作开发UNIX。他的主要工作是改造B语言,使其更加成熟。其中最重要的改动是,把数据类型的概念引入到B语言中。丹尼斯•里奇在B语言中增加了字符类型,同时也把B语言的编译器修改为生成PDP-11的机器指令。他称这个稍微扩展的语言为NB,也就是“New B”。

​图2  肯•汤普森(左)和丹尼斯•里奇(右)

图2 肯•汤普森(左)和丹尼斯•里奇(右)

1972年,丹尼斯•里奇经过不懈地努力,在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,也就是C语言。

1973年初,C语言的主体完成。汤普森和里奇迫不及待地开始用C语言全部重写了UNIX。此时,他们一门心思地投入到C语言和UNIX的开发中,完全沉浸在编程的乐趣中,早就忘了那个曾经的Space Travel游戏。

1977年,丹尼斯•里奇发表了不依赖于具体机器系统的C语言编译文本《可移植的C语言编译程序》。

1978年,美国电话电报公司贝尔实验室正式发布了C语言。布莱恩•柯林汉(Brian Kernighan)和丹尼斯•里奇共著的《The C Programming Language》(《C程序设计语言》)出版了。这本书被C语言开发者们称为“K&R”,很多年来都被当作C语言的非正式标准说明。人们称这个版本的C语言为K&R C。

1983年,ANSI为了让C语言健康地发展下去,在当年夏天成立了一个在CBEMA指导下的X3J11委员会,制定C语言标准。该委员会由C语言作者和应用程序员、硬件厂商,编译器及其他软件工具生产商、软件设计师、顾问、学术界人士组成。

1989年,X3J11委员会在年底发布了ANSI89报告。随后,ANSI发布了第一个完整的C语言标准:ANSI X3.159-1989,简称“C89”,也就是ANSI C或C89标准。

1990年,国际标准化组织(International Organization for Standards,简称ISO)和国际电工委员会(IEC)接受了1989年的ANSI C为ISO C的标准,命名为ISO/IEC 9899:1990。由于该标准发布于1990年,所以也称之为C90标准(不过习惯上仍然叫C89标准)。实际上,C90标准与C89标准完全等同。

1995年,ISO对C90做了一些修订,即“1995基准增补1(ISO/IEC/9899/AMD1:1995)”。在ANSI标准化后,尽管C语言本身在继续改进,但是C语言的标准在一段很长的时间内都保持不变。

1999年,在做了一些必要的修正和完善后,ISO发布了新的C语言标准,命名为ISO/IEC 9899:1999,简称“C99”。

2011年12月8日,ISO正式发布了C语言的最新标准C11。由于之前不知道具体的发布时间,曾被称为C1X,官方名称为ISO/IEC 9899:2011,简称“C11”。新标准提高了对C++的兼容性,并增加了一些新特性。

 2.   C语言及其各标准的变化

在1973至1980年间(从C语言主体完成到C语言标准发布之前),特别是1977年左右,C语言的变化主要集中在考虑可移植性和类型安全上,探讨如何处理将大量代码移植到新平台时出现和潜在的问题。在这时期,C语言增加了unsigned、long、union和枚举类型。在此之前,C语言还保留着很多无类型的特征。例如在早期语言手册或代码中,指针与整型内存索引几乎没有区别;字符指针和无符号整数的算术特性相似,很容易让人混淆。添加unsigned类型使得无符号整数的运算区别于指针运算。另外,早期C语言还允许整数与指针之间的赋值(即使在当时,这种做法也不受鼓励)。随后,C语言引入了一个类型转换符号(在Algol 68中被称作“cast”),专门用于类型转换。

到了1982年,虽然K&R C一直被当成C语言的非正式标准,但是它却不能很好地反应实际使用中的C语言。尤其是它没有提及void和enum类型。虽然《The C Programming Language》中提到了(构成)结构体的新方式,但是在该书发表后C语言才支持与结构体相关的一些操作,包括对其赋值、将其传递给函数和从函数返回等。尽管AT&T发布的编译器和大多数编译器供应商都很快地添加了这些变化,但是当时仍然没有一个完整、权威的语言描述。C语言亟需进行标准化。

1983年,ANSI为制定C语言标准成立了X3J11委员会。该委员会对C语言进行了一项重大改变,借鉴了C++[Stroustrup 86]的做法,在函数签名中添加了形参的类型。在此之前,C语言的外部函数声明是这样的:

double sin();

这种声明只能说明sin是一个返回double类型值的函数。而改进后的声明是这样的:

double sin(double);

该声明显式表示了函数形参的类型,更方便进行类型检查和转换。同时,委员会也意识到,虽然新的声明形式更好,但是直接废除旧式风格的函数声明和定义并不合适。这就不得不妥协,允许两种形式共存。

C语言本身并未提供输入/输出或任何其它与外界交互的方式,而仅依赖一套标准函数。X3J11委员会意识到详尽地描述标准C库与描述C语言本身同等重要,于是花费了大量时间来设计库函数,并将其写入文档。另外,X3J11委员会还对C语言其他方面进行了一些小的改动。比如,增添了两个类型限定符:const和volatile,改进了不同类型的转换规则等。尽管如此,在整个标准化过程中,C语言的核心部分并未改变。大部分重要的改动都发生在语言的外层:预处理器和库函数。预处理器主要是执行宏替换的功能,使用着与语言其他部分截然不同的规则。预处理器与编译器之间的交互一直描述得不太清楚,X3J11试图解决这一问题。显然,C89标准比K&R C给出的解释更好更全面。另一方面,在发布的C89标准中并未正规化定义C语言的语义,从而导致了在一些小细节上仍存在争议。

下面总结了一下C语言各标准的一些主要变化

K&R C引入了以下几个主要的语言特性:

1.      标准I/O库

2.      新增struct、long int、unsigned int数据类型

3.      组合操作符=op的形式改为op=

  C89相对于K&R C的一些主要变化

1.      新增函数原型,对函数的输入参数进行严格类型检查

2.      新增void、const、volatile、signed、enum关键字,删除了entry关键字

3.      允许结构本身作为参数传递给函数

4.      新增#elif、#error、#line、#pragma预处理命令

5.      定义固有宏:_ _LINE_ _、_ _FILE_ _、_ _DATE_ _、_ _TIME_ _、_ _STDC_ _

6.      增加了真正的标准库

 C99相对于C89的一些主要变化

1.      新增restrict指针

2.      新增inline函数说明符,支持内联函数

3.      新增_Bool、long long int、unsigned long long int数据类型

4.      增强printf()和scanf()函数组

5.      增强数组,支持可变长数组,允许数组长度在运行时才确定,可在数组声明中使用restric、volatile、const关键字

6.      扩充了标准库和头文件,新增_ _func_ _预定义标识符

7.      支持复合赋值

8.      支持//单行注释

9.      支持变长数组,

10.   支持在for语句的初始化部分定义一个或多个变量

11.   修改了一些预处理程序

12.   变量声明不必放在语句块的开头

13.   初始化结构时允许对特定元素赋值

14.   取消函数返回类型默认为int的规定

C11相对于C99的一些主要变化

1.      新增_Noreturn函数说明符

2.      新增_Static_assert()静态断言

3.      新增_Generic关键字,支持轻量级泛型编程

4.      新增_Atomic类型限定符、<stdatomic.h>头文件

5.      新增_Thread_local存储类说明符、<threads.h>头文件,支持多线程

6.      新增_Alignas对齐说明符、_Alignof操作符、aligned_alloc()函数、<stdalign.h>头文件

7.      新增了一些处理浮点数和复数的宏

8.      新增<uchar.h>头文件,支持增强的Unicode

9.      新增at_quick_exit()、quick_exit()函数

10.   新增边界检查函数结构,定义了新的安全的函数,例如fopen_s()、strcat_s()等

11.   在<time.h>头文件中新增timespec结构体,时间单位为纳秒;原来的timeval结构体,时间单位为毫秒

12.   支持匿名结构体、联合体

13.   支持新的fopen()模式,增加了新的创建、打开模式“x”

14.   删除了gets()函数(C99中已不推荐使用),提供了更安全的替代函数gets_s()

 3.   本书各版本的变化及影响

《C Primer Plus》1984年第1版问世时,用C语言编程的人并不多,许多人都是在这本书的帮助下掌握了C语言。也就是从那时起,C语言开始蓬勃发展。《C Primer Plus》一直都深受编程爱好者的欢迎,自问世以来各版本累计销售量已经超过55万本。

1984年1月,《C Primer Plus》第1版问世。那个时候,大家都以《The C Programming Language》作为C语言实际使用的非正式标准说明。全书448页。

1993年4月,《C Primer Plus》第2版出版。距第1版出版,已过了9年。这些年里,X3J11委员会于1989年底发布了C89标准。1990年,ANSI接受了C89,并命名为ISO/IEC 9899:1990,也就是大家熟知的C90标准(C89和C90标准完全等同)。本书为适应C90标准,做了全面更新。

1999年,《C Primer Plus》第3版出版。在过去的6年里,ISO对C90做了一些修订。本书也根据这些修订进行了更新。虽然C语言本身在不断地改进和完善,但是从1990年C90标准发布后,C语言标准近十年都保持不变。

2001年9月,《C Primer Plus》第4版出版。作者Stephen Prata的目标始终未变,他致力于写一本具有启发性、条理清晰的C语言入门书。书中也保持着一惯的风格,用许多短小的代码示例展示语言概念,让读者明白会用。在每章末尾设置复习题和编程练习,帮助读者消化一些容易混淆和难以理解的概念。1999年,经过多年的修正和完善,ANSI正式发布了C99标准。本书也为了适应C99标准,在第3版发行仅两年就马上根据当时的最新标准,对本书进行了更新。经过前几版的修订,全书从第1版的448页增加到970页。

2004年12月,《C Primer Plus》第5版出版。在C99标准发布后,又掀起了学习C语言的高潮。为了让大家更好地学习和理解C语言,作者在不改动章节布局的前提下,新增了大量插图和表格,以阐明一些不容易用语言描述清楚的概念。全书特别标出了C语言的主要特性,便于读者日后参考和回顾。在这一版中,作者也反复强调读者应该亲自动手把代码示例输入系统中运行。实践和理论结合才能牢固地掌握所学的知识。除此之外,还鼓励读者要多尝试修改程序,看看编译器给出什么警告,体会一下运行修改后的代码会出现什么不同的情况。练习得越多,思考得越多,学得就越多,掌握得就越牢。全书984页。

2013年12月,《C Primer Plus》第6版出版。2011年12月,ISO正式发布了C语言的最新标准C11。相对于第5版,这一版根据最新的C11标准,做了全面的更新,增加了许多内容。正如介绍中说的,随着C语言的发展,从早期的非正式K&R C标准,到1990年的C90标准、1999年的C99标准,再到2011年的C11标准,本书也在日趋成熟和完善。全书1080页。

从以上《C Primer Plus》各版本的历史看,最明显的变化就是全书的页数。从最初的448页剧增到最新版的1080页,这也从另一个角度见证了C语言的发展历程。可以说,这本书是和C语言一起成长起来的。在亚马逊上,本书的各版本一直都是好评如潮。虽然书越来越厚了,但是作者的写作思路和目标一直都很有清晰。对于中高级读者而言,这本书的讲解可能稍显啰嗦,还时常重复讲到一些已经介绍过的概念。但是,初学者需要的就是这些。这本书主要是针对初学者编写的,作者在书中也提到过,假设读者是没有任何编程经验的。在阅读本书的过程中,能感受到作者循循善诱的指导。初学者能毫无压力地自学完本书。

其实,现在市面上许多编程书籍对初学者都不太友好。看上去厚厚的一本,学习的过程中感觉自己学了很多,也记下了不少知识点。但是,在具体动手编程时,却往往一筹莫展。虽然打开了编译器,但却愣在那里不知道怎么做,这往往是初学者脚下的一块绊脚石。很多人就是在这里被绊倒,停止了学习的脚步。有些人为此大伤脑筋,刨根问底,似乎怎么学都不得法。究其问题的根源,不在读者。对初学者而言,特别是零基础的初学者,最需要的不是详尽深奥的原理分析,而是完整的代码示例。《C Primer Plus》这本书最大的优点就在于,至始至终都有详尽完整的代码示例。读者只需按部就班,把代码输入编译器就能运行程序。就算一开始什么也不懂,但是只要程序能运行,初学者就会对学习抱有信心和兴趣。这本书给了初学者宝贵的信心和继续学下去的动力。一边看代码,一边阅读后面逐条代码的详细分析。随着学习的深入,反复敲打代码更有助于理解晦涩抽象的概念。慢慢地,自己也会用了。看到自己写的代码编译通过时,那种发自内心的愉悦是对学习最大的鼓励和肯定。这本《C Primer Plus》的确是学习C语言不可多得的良师益友。

 4.   关于作者

Stephen Prata是加利福尼亚的马林学院(肯特菲尔德)的一位物理学和天文学教授,曾在教授天文学、物理学、离散数学和计算机程序设计课程,现已退休。他在加州理工学院获得学士学位,在加州大学伯克利分校获得博士学位。Stephen教授是美国天文学会的成员,也是富布赖特学者。他最早接触程序设计,就是为了用计算机给星团建模。Stephen撰写和与他人合著了十几本书籍,其中包括《C++ Primer Plus》和《Unix Primer Plus》。

 5.   目录导读

《C Primer Plus》第6版详细讲解了C语言的基本概念和编程技巧。值得一提的是,C99和C11新增的内容,在目录上均用括号特别注明,方便读者查阅。全书共17章,可分为三个部分。

第一部分预备篇(第1~2章),用较少的篇幅介绍学习C语言所需的预备知识。

  •   第1章介绍了C语言的历史和特性,简要介绍了编写程序的几个步骤和简单的编程机制。
  •   第2章概述了C语言编程的预备知识。

第二部分基础篇(第3~15章),每章都详细讲解了C语言的相关知识。包括数据类型、格式化输入/输出、运算符、表达式、语句、循环、字符输入和输出、函数、数组和指针、字符和字符串函数、内存管理、文件输入输出、结构、位操作等。

  •   第3章介绍C语言的两大数据类型:整数类型和浮点数类型,讲解这些数据类型是什么、如何声明和使用它们。除此之外,还介绍了常量和变量的区别。
  •   第4章重点介绍C语言的输入和输出(printf()和scanf()),简要介绍#include预处理器指令和const修饰符,并介绍如何定义、使用明示常量。
  •   第5章介绍C语言的各种运算符、表达式和语句。在熟悉了如何表示数据后,就可以学习如何处理数据了。本章还介绍了C语言的许多特性(包括循环),帮助读者组织程序。
  •   第6章重点讲解C语言的控制语句:循环(for、while和do while)。
  •   第7章重点讲解C语言的控制语句:分支和跳转(if、if else、switch、goto)
  •   第8章开始介绍C语言的字符输入/输出(printf()、scanf()、getchar()、putchar()等),以及一些与输入验证相关的问题和解决方案。
  •   第9章介绍函数。既然已经学会使用C标准库的一些函数,本章要进一步地学习如何创建自己的函数。本章一边巩固以前学过的知识,一边对知识做进一步的扩展。
  •   第10章介绍数组和指针,着重讲解如何编写处理数组的函数以及数组和指针的密切关系。
  •   第11章介绍字符串和字符串函数。利用C标准库中提供的大量函数来处理字符串,进一步提高自己的编程水平。
  •  第12章介绍存储类别、链接和内存管理。要更好地控制程序,必须掌握C语言的内存管理系统。隔离使用内存来储存数据是设计程序的一个要点。
  •   第13章介绍文件的输入和输出。如何使用C标准I/O系列的函数来处理文件。
  •   第14章介绍C结构和其他数据形式。
  •   第15章介绍位操作。通过介绍位、字节、二进制记数法和其他进制记数系统的一些背景知识,学习如何处理位运算。提高用C程序处理硬件问题的能力。

第三部分提高篇(第16~17章,附录B参考资料),介绍C预处理器、C库和高级数据表示。附录的参考资料中详细介绍了C语言和编程方面的一些补充知识,还包括新增的C99和C11的标准ANSI C库。

  •   第16章介绍C预处理器和C库。
  •   第17章介绍高级数据表示。包括一些算法和抽象数据类型(ADT)的概念,为将来学习面向对象程序设计(OOP)以及C++做好准备。

由于本书主要针对初学者编写,在讲解知识点时力求详细,以帮助没有编程经验的初学者们理解抽象的概念。书中以完整的程序为例,讲解C语言的知识要点和注意事项。同时,完整的代码示例中还附有详细的注释说明,帮助初学者更好地理解程序。每章末设计了大量复习题和编程练习,帮助读者巩固所学知识和提高实际编程能力。本书可作为C语言的教材,适用于需要系统学习C语言的初学者,也适用于巩固C语言知识或希望进一步提高编程技术的程序员。

  1.   如果之前没有编程经验,推荐按章节顺序依次研读。后面章节一般是建立在理解了前面章节知识的前提下,由浅入深、循序渐进地讲解。希望初学者不要跳读,以免增加阅读难度。
  2.   如果有其他语言的编程经验,可快速浏览第一部分(第1~2章),大致了解C语言的历史和基本特性。再根据自身的具体情况和兴趣,有针对性地阅读第二部分(第3~15章)和第三部分(第16~17章)的内容,对比哪些特性是C语言特有的,哪些特性是其他语言共有的。
  3.   如果之前学过C语言,长时间不用遗忘或生疏了,可快速阅读第一部分和第二部分,查缺补漏。如果对一些高级主题感兴趣,可研读第三部分和附录B参考资料。

 6.   思维导图​

​​《C Primer Plus(第6版)中文版》

 【美】Stephen Prata(史蒂芬 普拉达)著 

点击封面购买纸书

经久不衰的C语言畅销经典教程
针对C11标准进行全面更新 

与以前的版本一样,作者的目标仍旧是为读者提供一本入门型、条理清晰、见解深刻的C语言教程。作者把基础的编程概念与C语言的细节很好地融合在一起,并通过大量短小精悍的示例同时演示一两个概念,通过学以致用的方式鼓励读者掌握新的主题。

每章末尾的复习题和编程练习题进一步强化了重要的信息,有助于读者理解和消化那些难以理解的概念。本书采用了友好、易于使用的编排方式,不仅适合打算认真学习C语言编程的学生阅读,也适合那些精通其他编程语言,但希望更好地掌握C语言这门核心语言的开发人员阅读。


今日话题

说说你的第一学的第一种编程语言是什么?读过哪些异步相关图书?留言+转发本活动到朋友圈,小编将抽奖选出1名读者赠送异步新书一本。留言后,加小编微信 louisenanjing 回复: 抽奖  加你进群抽奖。

延伸推荐

2018年2月新书

2018年1月重磅新书

小学生开始学Python,最接近AI的编程语言:安利一波Python书单

政策升温:大家都在学大数据,一大波好书推荐

8本新书,送出一本你喜欢的

AI经典书单| 入门人工智能该读哪些书?

​长按二维码,可以关注我们哟

每天与你分享IT好文。


“异步图书”后台回复“关注”,即可免费获得2000门在线视频课程;推荐朋友关注根据提示获取赠书链接,免费得异步图书一本。赶紧来参加哦!

点击阅读原文,购买C Primer Plus(第6版)中文版

阅读原文

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值