作者 谢恩铭 转载请注明出处
公众号「程序员联盟」(微信号:ProgrammerLeague )
原文:https://www.jianshu.com/p/a8c3a44f57ef


《C++探索之旅》全系列

内容简介


  1. 开宗明义
  2. 什么是C++
  3. 什么是程序
  4. 编程语言
  5. C++与其他语言的比较
  6. C++的历史
  7. C++经典书籍
  8. 总结
  9. 第一部分第二课预告

1. 开宗明义


亲爱的读者,您是否对 C++ 感兴趣,但因为 C++ 看起来很难,或者别人对你说 C++ 挺难的,你不知道如何下口,哦,不,是如何下手 ?

别担心,这个系列教程就是为 C++ 初学者准备的。当然了,此课程也适合进阶。

不可否认,C++ 是一门非常著名的语言。几乎学计算机的同学都难免会接触一下 C++,中国的大学课堂一般也是先学 C 语言入门,然后就是 Java 或者 C++。

C++ 这门语言的使用很广泛,特别是在游戏开发领域,C++ 的性能和无限可能性使得其几乎独占鳌头。

我们经常听到说 C++ 是 C 语言的后继。实际上,这两门语言虽然有点像,但还是不一样的。C++ 加入了很多新的特性,比如面向对象编程(OOP,Object-Oriented Programmation)。

小编一直觉得:学编程,第一门语言最好是C语言。有兴趣的朋友可以参看我的 《C语言探索之旅》

当然有的朋友见解不同,觉得 Python,Java 等相对比较好上手的语言更适合。

C,C++,Java 这三门语言是可以做到相辅相成,融会贯通的。事实上,C++ 的发明受了 C 语言的启发,而 Java 的发明又受了 C++ 的启发。

个人浅见认为:
有了 C 语言的基础,再去学 C++ 和 Java,会轻松很多。
当然,如果你有余力学一下汇编语言,那会更有帮助,请参见我的 学习汇编对编程有什么帮助?如何学习

在这个系列课程中,我们不仅会一点点带大家领略 C++ 的奇妙之处,后面还将带大家来探索一个 C++ 的库:Qt。

Qt 这个库非常强大,已经超越了一个库单纯的范畴,甚至可以说是一套体系。在嵌入式领域,Qt 也大有可为。Qt 开发也非常方便,独有的「信号-槽」的机制可以大大加快开发速度。

如果当时诺基亚没有抛弃 Qt,用 Qt 设计的 Meego 系统来搭载手机而不是弃 Intel (英特尔)转投入「霸道总裁」 Microsoft(微软)的怀抱,那也许 C++ 目前会更火。

2. 什么是C++


C++ 一般我们也可以写成 CPP,或者 C Plus Plus( Plus是英语「加上」、「更多」的意思)。所以从名字上我们就可以看出一点端倪。

既然我们有C语言,那 C++ 岂不是意味着「在C语言的基础上再多加了一些东西」么?

其实是可以这样理解的,虽然我们一般还是会把 C 语言和 C++ 看成两门不同的语言。但是确实 C++ 的发明受了 C 语言的启发。

读者朋友,如果你还有兴趣继续看下去,说明你对编程有一定热情,或者有兴趣想学着编程试试。

记得之前网上有一个视频,是微软创始人 比尔·盖茨、Facebook 创始人马克·扎克伯格、Twitter 联合创始人杰克·多西以及 Dropbox 联合创始人兼 CEO Drew Houston 和 Zappos CEO 谢家华 等,同时也包括了体育界和政界的一些明星,比如 NBA 迈阿密热火队球星 克里斯·波什 和美国前总统 克林顿 和副总统 戈尔 等联合录制的一个视频,鼓励全民学编程。

编程其实没有那么难,确实人人都可以学编程的,现在编程的门槛越来越低了,网上好的教程和资源太多。新的编程语言也设计得越来越符合人的思维,简单易用。

在这一课里,我们会尝试解答大家初遇 C++ 的一些问题。

不过不要忘了,这个课程是给初学者的,所以你并不需要担心,即使你从来没有写过一行代码,也不知道编程和程序是什么。

可以说这个系列课程不需要你预先有任何编程知识,只需要你有阅读的能力。

我们就是从零开始。当然,如果你有编程基础,那这个 C++ 的课程会更容易学。

唯一需要大家做到的,就是循序渐进地学习这个系列课程,并且认真独立完成我们的各种练习题和项目。

准备好了么?C++ 这座「太行王屋山」,我们来征服它吧!

3. 什么是程序


程序( Program )是信息技术的基础。你在电脑上可以做各种操作,就要归功于运行在电脑里的各种程序。

在我们的 《C语言探索之旅》第一部分第一课:什么是编程? 里已经做了比较详细的介绍了,但是因为这个 C++ 的系列教程是面向初学者的,所以小编不厌其烦地再讲一遍。尽量不重复。

我们先看以下截图:

上面的截图,是我在 Windows 操作系统里截取的。

可以看到,我们这里打开了三个不同的窗口,其实就对应了三个不同的程序:

  • 火狐浏览器:可以上网,我们打开了三个不同的页面。

  • 文件管理器:可以管理我们 Windows 系统里的各种文件。

  • 记事本:Windows 下的基础文本编辑器。

我们可以看到,这三个程序设计的目的都是很明确的,各司其职:浏览器负责上网浏览网页,文件管理器管理电脑的文件,记事本使我们可以编辑文档。

我们也可以举一些大家熟悉的游戏,比如超级玛丽( SuperMario ),百战天虫( Worms,超级好玩的游戏,曾经和堂哥在我初中时玩的... 小编你又不淡定了),星际争霸( Starcraft ),等等。这些也都是程序。

上面的截图就是星际争霸的游戏画面。怎么样?很酷炫吧。是不是也想要学好编程去开发游戏了?

当然了,现在随着 Unity 3D 的崛起,开发游戏比以前容易多了。

星际争霸 2 的地图编辑器就是用 C / C++ 来写的。而一般编写单机 PC / 主机游戏现在都是 C++ 加上一个脚本语言(比如 Lua,这地方不需要脚本引擎多么高性能,够用就好)。

所以,是不是对于 C++ 的兴趣又浓厚了一点呢?当然,游戏,我们开发是好,玩游戏丧志我们是绝对不推荐的。

小编以过来人的经验告诉大家,自己写游戏绝对比你玩游戏有成就感一万倍。

运行自己写的游戏,那酸爽~,不言而喻。而且会开发游戏之后,你也自然不会沉迷游戏了。请看我的 现身说法 | 玩游戏不如自己开发游戏 一文。

扯回正题~

我们上面举了三个程序的例子,又给大家看了一个星际争霸(也是程序)的游戏截图。可能大家会认为,程序就是都能看得见的。但其实并不尽然,并不是所有程序都是可见的。

比如一些后台运行的服务( service ),或者很多系统程序(比如防火墙等)都是不可见的。虽然不可见,但是这些程序还是兢兢业业地为你工作噢。

虽然上面的星际争霸的截图可能让你很想马上学会 C++ 编程,然后开发属于自己的游戏。但是不要急,一口气是吃不成一个胖子的,只能吹胀一头牛...

像星际争霸这样复杂的大型游戏,需要十多个人(不都是编程,也需要美工,动画制作等)全时间工作几年才能开发出来。所以一开始我们要有耐心,可以从一些小程序开始(游戏是一种程序)。

在这个系列课程中,小编会带大家一起开发一些 C++ 程序,也会有游戏。

4. 编程语言


你的计算机(电脑)真的是一个奇怪又复杂的家伙,这样说已经算很给它面子了。

我们给它传递命令,只能输送给它 0 或 1(因为电脑里面有大大小小的数不胜数的晶体管,而它们被用来做「开关」,0 和 1 正好可以用来表示「开启」或「关闭」这两个状态,所以电脑最底层其实都是 0 和 1 这样的二进制码)。

打个比方,我要让电脑做以下的事:「为我打开一个文件夹」。我实际上输给电脑的是(是我随便写的,我并不知道怎么转换这句话到二进制码):

010100111011001100111101010

正如你看到的,这就是你的电脑所会的语言,被称为「二进制语言」。它也只会这门语言,可以看到这门语言完全不容易理解。

所以,我们的第一个真正的问题来了:「怎么和电脑对话呢,难道只能用 0 和 1 吗?」

你的电脑既不讲中文也不讲英语。难道我们也要学这门「二进制语言」吗?

幸亏不必。假如用这门语言编写星际争霸这样的游戏,那大概需要一百年吧...

为了简单起见,我们的计算机学者们就想到:先用其他简单一些、便于理解的语言(有点像中间人那样)编写程序,之后再把它翻译成电脑的二进制语言。

这类语言就被统称为「编程语言」。

当然最不容易的,就是要编写这样一个「翻译」程序。幸亏计算机学者们已经把这样的翻译程序写好了,我们也没必要重新做了(着实松了一口气)。

所以我们要做的就是告诉电脑:「为我打开一个文件夹」,这句话会被翻译成电脑的二进制码:

010100111011001100111101010

今天,全球存在上百种编程语言,如果你百度或者 Google 一下,就可以找到一个编程语言的列表。

我们就不一一列举了。这些编程语言不尽相同,各有特色,但是都有一个共同的目的:使我们可以用比二进制码更简单的方式和电脑「对话」。

一般的编程语言都是这样工作的:

  1. 我们用一门编程语言(例如 C++ )的指令来写我们的程序(源代码)

  2. 这些源代码被一个「翻译」程序翻译成电脑能理解的二进制码

  3. 电脑就能读取最终的二进制码,来执行我们要它执行的事啦

我们用一张图来总结一下:

这个「翻译」程序的正式名字是:编译器(英语是 Compiler )。这是一个必不可少的工具(当然,对于解释型语言,如 Python,就需要解释器了。我们暂不深究,大家可以百度一下:编译型语言和解释型语言。但其实最基本的原理是一样的:都需要一个「翻译」程序把源代码翻译成二进制码)。

那么,我们如何在这上百种编程语言中选取一种来学习呢?哪一个是最好的呢?C++ 是好的选择吗?

其实,一个程序员通常会几种编程语言,很少有只会一种的。

就好像我们中国人会说中文,但一般也会英语吧。有的人更厉害,会好几种语言。

当然了,初学编程,我们并不需要几种语言同时一起学,那会分散注意力。

一开始,我们只要学一种就好了,等融会贯通了以后,学其他的就简便很多。比如你英语好,那么学法语就会比只会中文的人更轻松。

好消息是你可以随自己喜欢,想先学哪种编程语言就先学哪种。虽然小编个人推荐先从 C 语言开始,当然从 C++ 或 Java 开始也未尝不可。你从 Python 开始也可以。

不过既然这个系列课程是关于 C++ 的(小编你没忘记就好...),那么我们就来看看 C++ 相比于其他编程语言的独有特色吧。

5. C++与其他语言的比较


在上百种编程语言中,不可讳言,有些确实比较著名,而有些却几乎无人问津。

这和人类的语言是类似的:总有那么几种语言如英语,法语,西班牙语,德语,日语,中文,是比较流行的,而爪哇语,毛里求斯语,或者非洲某部落的语言,就很少有人学习了。

C++ 毫无疑问是最流行的编程语言之一,在著名的 http://langpop.com/ (貌似最近上不去了)网上有很多编程语言的排名,以图表的形式:

上图是 Google 搜索的关键字数。可以看到:C 语言,Java 和 C++ 是前三名。

再如著名的编程语言排行榜 TIOBE 在 2017 年 4 月的榜单:

TIOBE 排行榜是根据互联网上有经验的程序员、课程和第三方厂商的数量,并使用搜索引擎(如 Google、Bing、Yahoo!)以及Wikipedia、Amazon、YouTube 统计出排名数据,只是反映某个编程语言的热门程度,并不能说明一门编程语言好不好,或者一门语言所编写的代码数量多少。

那么问题来了:是否应该将一门语言的流行程度作为编程首选语言的考虑因素呢?

虽然并不是一定的,但确是一个考量因素。因为有些语言很有意思或者设计得很好,但使用不是太多,比如 Lisp 语言。

如果一门编程语言使用不广泛,就有个缺点:「技术支持少,不容易找到能为你答疑解惑的人」。

这也是 C++ 适合作为首选语言的原因。你在这条学习路上不会孤单,有很多仁人志士都已经「上了贼船」,随时为你保驾护航。

当然了,除了流行性,编程语言之间的比较还有另一个标准:高级语言还是低级语言。

我们说有些语言是高级语言,另一些则是低级语言。

这里的「高级」与「低级」并不是好与不好的区别,而是偏离二进制码(电脑的机器语言)越远就越高级,越接近人类思维模式就越高级。

一般来说,高级语言使用更简便,编程更快捷。而低级语言往往相对难一些,不过更易于控制电脑。所以说这是双刃剑。

那么 C++ 呢?

可以把 C++ 归为「低级语言」。再声明一次,这决不是说它比较低等。你想把它归为「高级语言」也没有关系。

「高级语言」和「低级语言」是一种比较而言,如果和二进制码或者汇编语言相比,那么 C 语言和 C++ 也算是高级语言了。

虽然说 C++ 编程可以是很复杂的,但是 C++ 却非常强大,而且运行速度很快。

下图是一个语言层次的展示:

可以看到,在上图中,有一种语言最接近机器的二进制码语言,那就是汇编(英语是 Assembly ),也是大家有空值得学习的语言。

学习汇编不需要太深入,入门就好,可以使你更好地理解内存机制,指针是怎么回事,还有电脑工作的一些原理。

推荐王爽老师的 《汇编语言》 这本书,写得很好。不枯燥,而且由浅入深。

C++的优势


  • 很流行:我们从之前的图表已经看出,C++ 跻身全球最流行的编程语言前列。所以我们可以很轻松地在网上找到很多 C++ 的技术文档,编程实践,也有很多 C++ 的论坛,你可以提问,查找资料。

  • 运行速度快:算是运行速度非常快了。这从 C++ 是游戏领域热门语言就可知晓,因为很多大型游戏需要极快的运行速度。当然除了游戏,C++ 还被用于金融行业和军事的程序。

  • 可移植性,跨平台性:一个同样的 C++ 程序几乎可以不加修改地运行在 Windows,Linux 和 Mac OS 操作系统上,其他系统也类似。我们省去了重写程序的麻烦。

  • 众多第三方库:第三方库,有点类似语言的插件,或者扩展。对于编程语言来说,它一定自带了标准的库可供调用。比如一些基本的输入输出函数,是语言本身的标准库里定义好的。关于库和函数,我们之后的课程再讨论。Qt 就是一个很著名的 C++ 第三方库。我们可以用 Qt 来编写图形界面的各种程序。

  • 多种编程方式:我们可以用面向过程的方式编写 C++ 程序,也可以用其面向对象的特性,还有 STL 这样的标准模板库。这些多样的形式使得 C++ 异常灵活和强大,但是也比较复杂。之后我们都会学到。

当然,说了这么多 C++ 的优点,并不是说 C++ 就没有缺陷。它也有自己的缺点,特别是其复杂性,可以说 C++ 是目前最复杂的编程语言。就像 C 语言有不少缺陷和陷阱一样,建议阅读 《C陷阱与缺陷》 一书。

正如上面所说,C++ 算是和 C 语言一样比较偏底层的语言,这也给了我们直接操作内存的能力。但是能力越大,责任越大。假如未能正确使用 C++,那么我们的程序很容易卡死或者潜伏危机。

但也没什么好怕的,这个系列课程就是为了让大家能够很好地控制
C++ 这个很厉害的「熊孩子」,让它成为「功夫熊猫」。

C++程序之初见


为了给大家展示 C++ 程序到底大致是个啥样子,我们就给出一段代码,是最基本的:在屏幕上显示 Hello World 这两个英文单词(也就是「你好,世界」):

#include <iostream>
 
using namespace std;
 
int main()
{
  cout << "Hello World!" << endl;
  return 0;
}

是不是和 C 语言的 Hello World 例程很像呢。

6. C++的历史


要说 C++ 的历史,就先要回顾一下编程的历史。编程的历史虽然不是 long long time ago(很久很久以前),那也是 long time ago(很久以前)了。

一开始,计算机先驱们编程的时候,可没有今天那么好的条件呀。那时候哪有鼠标和键盘,只能用「打孔卡」这样的东西:

打孔卡是一块纸板,在预先知道的位置利用打洞与不打洞(表示开和关,类似 0 和 1 的二进制码)来表示数字消息。

摘自维基百科的小科普:

1801 年,法国人约瑟夫·玛丽·雅卡尔发明了打孔卡用在控制织布机织出的图案。

1880 年代,美国人口调查局职员霍列瑞斯发明了用于人口普查数据的穿孔卡片及机器,并用于 1890 年美国人口普查,仅 6 周就完成了统计。而此前 1880 年美国人口普查的数据全靠手工处理,历时 7 年才得出最终结果。霍列瑞斯创建的公司,发展为今日的 IBM

1890 年代至 20 世纪初,穿孔卡广泛运用在商业和相关文书。20 世纪期间,打孔卡应用在单位记录机作为输入端、处理和计算机程序。早期的数字电脑运用打孔机已输入信息的打孔卡当做计算机程序和数据的主要输入媒介。

1928 年,IBM 发明的 80 列、矩形孔卡片,成为事实上的标准。其工作原理如下:编号为 0 至 9,总计 10 行;以及一块区域,用于第
11、第 12 行(注意,没有编号为第 10 的行)。每列的穿孔组合用于表示单个字符。

IBM 为计算机科学做出如此大贡献。不愧是「蓝色巨人」,百年老字号。

语言的演化史


打孔卡在今天看来当然是极为低效的工具了,但在当时确实是好发明。

时代在进步,我们的编程工具和编程语言也在进步。

  • 1958 年:那个时候的电脑可不像今天这么小巧,最大的可以达到一间房子那么大,重达好几吨,耗电好几十千瓦,耗资几十万美元。那个时候出现了一种叫做 Algol 的编程语言。

  • 1960 至 1970 年:计算机先驱发明了新的语言,叫做 CPL,后来又发展成为 BCPL。后来被称为 B 语言。

  • 1970 年:老爷子 Dennis Ritchie(丹尼斯.里奇)来「踢馆」,发明了震惊世界的C语言。C 语言是目前绝大多数编程语言的鼻祖,很多语言就是用 C 语言来写成的,比如 C++,Java,Python,PHP,等等。目前仍是使用最多的语言之一,而且在嵌入式领域举足轻重。著名的操作系统都是 C 语言写的:Unix,Linux,Windows,Mac OS,等。

  • 1983 年:又过了十几年,我们本课程的主角:C++ 诞生了。C++其实是在 C 的基础上加了很多新的东西,使其变得更加强大,也能够用更多的形式编程。

那么问题来了:如果 C++ 被称为 C 语言的一种「演化版本」,那么为什么这么多人还仍旧使用 C 语言呢?为什么不直接选择更完善 C++ 呢?

因为不是每个人都需要 C++ 带来的额外功能的,C 语言更接近底层,所以 Windows,Linux 和 Mac OS 这样的操作系统都是用 C 语言为基础来设计的。

还有一个原因:C++ 确实比 C 语言更复杂一些。如果我可以用水果刀削苹果,那何必用青龙偃月刀呢。

C++的设计者


1983 年,Bjarne Stroustrup(本贾尼·斯特劳斯特卢普。这位前辈的名字好难记啊。不过他有个简称,就是 B.S,还好不是倒过来... 还是我们 C 语言的发明人 -- 老爷子 Dennis Ritchie 的名字比较好记,哈哈 :P )发明了 C++ 语言。原因是他对 C 语言的局限性有些不满意,想要发明一门有更多可能性的语言。

摘自百度百科的介绍:

Bjarne Stroustrup 于 1950 年出生于丹麦,先后毕业于丹麦阿鲁斯大学和英国剑桥大学,AT&T 大规模程序设计研究部门负责人,AT&T、贝尔实验室和 ACM 成员,现任德州农工大学计算机系首席教授。1979 年,B. S 开始开发明一种语言,当时称为 「C with Classes」(带类的 C ),后来演化为 C++。1998 年,ANSI/ISO C++ 标准建立,同年,B. S 推出了其经典著作《The C++ Programming Language》的第三版。

C++ 语言是以 C 语言为基础的,支持 C 语言的所有语法和几乎所有的技术,因此也有人把 C++ 语言看作是 C 语言的超集。同时 C++ 语言支持面向对象程序设计方法的所有概念,它是一种非常实用的、功能极为强大的程序语言,相对而言较难掌握。

事实证明,他做到了,C++ 确实很丰富和强大。这也使得很多后继的编程语言受到 C++ 的启发,比如 Java。

虽然 C++ 这门语言一把年纪了,但是现在仍旧不断在被更新。估计设计者们也知道 C++ 比较复杂,所以在新版本中有把它改简单一些,也增加更多现代编程元素。不过我觉得,不管怎么改,C++ 都摆脱不了其复杂性了,哈哈。

7. C++经典书籍


  • 《The C++ Programming Language》(《C++程序设计语言》):C++ 之父 Bjarne Stroustrup 写的书籍,还有比这更权威的么?不过对初学者可能有点难,就好像 Dennis Ritchie 写的《C程序设计语言》也是初学有点难。不仅对语言,而且对语言周边的一些如发展史、语义哲学都有比较详细的描述。对语言的描述较为全面,同时包含一部分和程序库相关联的知识,有一定深度,适合有一定编程语言基础的初学者,翻译质量不错,价格适中。

  • 《C++ Primer Plus》:适合C++初学者的书籍。和《C Primer Plus》类似都是不错的入门教材。覆盖面较全,章节安排比较合理,由浅入深,也很容易,因此失去了一些深度。价格比较便宜,但翻译质量略有不足。

  • 《C++ Primer》:久负盛名的 C++ 经典教程,其内容是 C++ 大师 Stanley B. Lippman 丰富的实践经验和 C++ 标准委员会原负责人 Josée Lajoie 对 C++ 标准深入理解的完美结合,已经帮助全球无数程序员学会了 C++。对 C++ 基本概念和技术全面而且权威的阐述,对现代 C++ 编程风格的强调,使本书成为 C++ 初学者的最佳指南;对于中高级程序员,本书也是不可或缺的参考书。比《C++ Primer Plus》难一些。

  • 《Effective C++》:C++ 牛人的大手笔,以条款的形式回答了程序员在使用 C++ 时经常提出的「应该注意些什么?」,「应该避免什么?」,「应该怎样去解决?」,「为什么?」 等问题。C++ 程序员想要让自己的水平上升到更高的档次,此书必看。价格稍贵,有一定难度,不适合初学者。

就推荐这四本吧,其他书籍还有很多。其实你能把这四本好好看完、学懂,那你就是 C++ 牛人了。如果你英语好,推荐看原版。

最后,不建议看谭浩强(不管是他的 C 语言书还是 C++ 书,都不推荐。学究味重,代码风格和编码思想不好(不良代码风格毁一生),也常有错误,总之越看越晕。)。纯属个人浅见。


读完此文,是不是心中也激动不已,想要撸起袖子,好好学一门编程语言呢?其实小编我撰写此文时何尝不是激动不已呢。
当年我读《观止-微软创建NT和未来的夺命狂奔》这样的编程报告文学作品时也是心潮澎湃,对于成为编程大牛无比向往。
其实编程真的很有趣,有一种创造和掌控一切的小***。当然,不要头脑发热就好。

8. 总结


  1. 程序使我们可以在电脑上做很多事情:上网,编辑文档,操作文件,玩游戏,等等。

  2. 为了实现各种程序,我们需要用计算机能懂得的指令来写。而编程语言就是来做这个活的,对应的指令我们称为源代码( Source Code )。

  3. 每种编程语言的语法都不一样,但是最终交给电脑执行前,都要先「翻译」成二进制码,因为我们的电脑兄只认得 0 和 1 组成的二进制码。这个将编程语言翻译成二进制码的工具被称为「编译器」( Compiler ),每种语言有对应的编译器。

  4. 在众多的编程语言中,C++ 是很流行和执行速度相对快的一门语言。可以说 C++ 是 C 语言的演进,因为在 C 语言所提供的基础编程概念上,它还加入了面向对象的编程模型和其他元素,我们之后的课程会介绍面向对象这一卓越的思想。

9. 第一部分第二课预告


今天的课就到这里,一起加油吧!

下一课我们学习:C++探索之旅 | 第一部分第二课:C++编程的必要软件


我是 谢恩铭,软件工程师,慕课网精英讲师 Oscar 老师,终生学习者。
热爱生活,喜欢游泳,略懂烹饪。
人生格言:「向着标杆直跑」