积极养育

（英）吉姆·克里斯蒂安著
于应机　李阳欢　林佳译

北京日报出版社

图书在版编目（CIP）数据

写给所有人的编程思维/（英）吉姆·克里斯蒂安著；于应机，李阳欢，林佳译.——北京：北京日报出版社，2019.4

ISBN 978-7-5477-3234-2

Ⅰ.①写…　Ⅱ.①吉……②于……③李……④林…　Ⅲ.①程序设计　Ⅳ.①TP311.1

中国版本图书馆CIP数据核字（2019）第024141号

北京版权保护中心外国图书合同登记号：01-2019-0472

Copyright©Batsford，2017

Text Copyright©Jim Christian，2017

Illustrations by Paul Boston

First published in Great Britain in 2017 by Batsford

An imprint of Pavilion Books Company Limited，43 Great Ormond Street, London

WC1N 3HZ

写给所有人的编程思维

出版发行：北京日报出版社

地址：北京市东城区东单三条8-16号东方广场东配楼四层

邮编：100005

电话：发行部：（010）65255876

总编室：（010）65252135

印刷：北京荣泰印刷有限公司

经销：各地新华书店

版次：2019年4月第1版

2019年4月第1次印刷

开本：710毫米×1000毫米1/16

印张：10.75

字数：150千字

定价：45.00元

版权所有，侵权必究，未经许可，不得转载

目录

扉页

版权信息

第一章 学会编程思维

学会编程思维

什么是编程？

计算机无处不在

计算机的特征

计算机如何工作？

计算机的出现

编程与计算机的历史

人人都能学会编程

世界需要更多的编程者

第二章 解决问题

解决问题

大脑是怎样工作的？

解决复杂的问题

脑力训练

更多逻辑谜题

约束条件

编程就是要简单

第三章 学习编程语言

学习编程语言

编程语言的语法规则

编程的形式

面向对象程序设计（OOP）

不同的数据类型

数据结构

算法

循环

条件语句

流畅的运算符

趣味函数

变量

调试

第四章 继续努力

还该做什么？

让世界变得更加美好

又到了做游戏的时间了吗？

生活，就是编程思维

再谈计算机思维

词汇表

拓展阅读

第一章　学会编程思维

学会编程思维

学习编程思维对于当代以及后代人们提高技术与知识水平至关重要。随着计算机在日常生活中的广泛应用、网络互联互通的进一步加深，人们的生活越来越便捷。现在，我们需要拥有这些工具，掌握其使用技能，这样才能获得有效的服务。明白了这一点，我们就可以借助现有的编程语言，进行人机“对话”，享受智能服务。而妨碍我们学习编程的一个常见问题是，不知从何学起，甚至怀疑能否学会。其实，不必为此担心，学习编程的途径有很多。

把编程语言的过去、现在，也许还有未来，紧紧联系在一起的，其实是一整套核心概念。你会发现，这些核心概念都源于计算机科学、逻辑学和数学——这也正是我们将要探讨的相关内容。希望通过这些知识和概念帮助你学会编程思维，而且不需要事先接触一行实际的代码。现在科技发展的速度实在太快，要想准确预测未来几年我们会使用什么先进技术与产品都非常困难，更不必说要解码了。所以我们希望你通过这些核心概念的学习，获取一套可以终生受益的工具，把自己武装起来，迎接各种挑战。

学习编程思维的过程，将帮助你培养批判性的思维方式，提升你的组织能力，增强你使用计算机的信心。这样，即便在以后的人生道路上遇到了编程术语的问题，也不会为之困扰。

你知道吗？

学习编程思维不分年龄，而且新学到的知识可以随时运用到学习、体育运动中去……什么事情都可能用得上哦！

在学习编程思维的过程中，不需要一台专用的计算机，也不需要什么专门的软件。一副骰子、一副扑克牌，甚至一支铅笔、一张纸，有了这些简单的工具，就可以学起来啦！

编程所涉及的知识非常广泛，不仅包括计算机的工作原理和思维模式等基础知识，还包括计算机科学常见的概念如循环、条件语句、变量等，甚至还需要探索和分析编程世界和自然世界的异同。本指导手册将会帮助你更好地探索这新奇而又趣味无穷的编程世界。

什么是编程？

当听到“代码”这个词语时，你会想到什么呢？也许是一种密码，其文字和符号可以相互转换，目的在于防止信息落入坏人之手；或者是一种有趣的交流方式，用于朋友之间传递信息，避免他人知晓其中的秘密。是的，你猜得没错！编码就是把获得的信息转换成其他形式的过程。而解码正好相反，解码是收集代码信息，将其转换成简明易懂的语言文字。

你知道吗？

时尚超模卡莉·克劳斯、著名歌手和音乐制作人Wam这些大明星都学过编程，他们都在借助编程的方式展现自己的创造力呢！

计算机编程的过程与之十分相似，就是将人的想法、思维过程转换成计算机要执行的动作。而要实现这一过程，我们就需要编程语言的帮助。编程语言能在程序员和计算机之间架起沟通的桥梁，将我们易于理解的话语翻译成计算机可以读懂的数字语言——二进制。随后，我们将会学习二进制的相关内容（见第019页）。

有一点很重要，请一定要明白：无论计算机多么强大，真正强大的还是人的大脑！程序员就是这样一群人，他们能让计算机做本来只有人才能做的事情。所以，我们赶紧开始学习编程吧！

计算机无处不在

如果四处观察一下，你就会发现，如今计算机真可谓无处不在。家中、办公室里、学校里随时都能见到计算机的身影，外出走走也随处可见。而计算机最常出现的地方就是我们的口袋，没错，就是智能手机。事实上，我们口袋中的这台计算机比起大约50年前将宇航员送上月球的那台计算机可是要强大多了！且不说体积还如此之小，过去的计算机，只能实现特定的功能，还是个庞然大物，要占好几间房子。现如今，计算机甚至可以戴在手腕上，而且还能轻易完成多项任务。智能手机今天所能够执行的任务，在25年前可是需要特定的、昂贵的设备才能完成的。试想一下，在你的口袋里装上一部手机、一部数码相机、一台摄像机、一个显示器、一个计算器等，那将会是怎样的情形呢？

计算机太普遍了，我们每天都在用计算机处理问题、进行娱乐。或许，正是太习惯于计算机无处不在的生活，我们都不会去想，其实身边那么多东西都是计算机。那么下面，我们就花点时间看一看那些我们几乎天天都在使用的计算机吧！

家中的计算机

你可能会：

·用智能手机定闹钟、打电话、拍照、玩游戏。

·使用可穿戴的健康监测器，帮你跟踪自己的身体状况。

·用平板电脑上网发邮件、浏览网页、访问社交媒体。

·利用笔记本电脑或台式计算机完成更多特定的任务，如编辑影像资料、创作音乐、玩游戏。

·使用智能仪表测算家中采暖、用电的情况。

·利用智能语音设备订购日用百货、播放音乐、实现网上搜索。

·用智能牙刷显示你花多长时间刷牙。

家里以外的计算机

你可能会遇到的计算机：

·在商店中买东西结账时，计算机会结算价钱、核对清单，然后收取钱款。

·自动取款机（ATM）能帮助我们查看账户余额、支取钱款。

·机场护照查验处的计算机利用面部识别技术，能确保我们的旅行更加安全、便捷。

·交通信号灯利用一套探测系统，能够持续对交通状况做出反应，保证行人安全通过马路。

·某些旅行卡中含有芯片，刷卡就可以使用。

·安保系统能够通过摄像头和运动传感器监控区域内的情况。

·拥有eReader（电子书），可以随时随地阅读。

这样的例子真是不胜枚举。如今，还有一种趋势，家中的物件内置计算机系统，具备联网能力，就能够“说话”，甚至做些我们根本意料不到的事情。比方说，滤水器损坏时能够自动要求更换；电灯泡只要智能手机发出指令，就能变换色彩。这些其实都是新趋势物联网（IoT）的具体实例。在物联网中，用途单一的日常物件如水壶、门铃，在其中置入计算机芯片，使其具备网络联通能力，都可以“智能”起来。

不过，以上列举的种种物件，无论什么用途，都要依赖计算机和程序员才能正常运转。

计算机的特征

一般来说，在家中依靠电流或电池运转的各种电器设备，大都依靠计算机程序运行，也都具备着现代计算机部分甚至全部的特征。

计算机的组成部分

各式计算机的外观看起来千差万别。一般来说，我们见到的有手机、平板电脑、台式计算机、笔记本电脑，它们都以不同的方式运行，但是其外壳之内却是大同小异。下面，我们就一起打开计算机，了解它的内部结构。

微处理器

在计算机系统中，微处理器是负责绝大多数“思维”工作的组件，扮演着计算机大脑的角色。微处理器中可能拥有不止一个核心。微处理器的核越多，大脑就越强大，每秒能够运行的指令也就越多。

微处理器也称为中央处理器或CPU。在微处理器的内部，有着成千上万个开关等待着电信号的到来，电信号通过通道和闸门的开或关，以二进制数的形式生成。

随机存储器⸺RAM

这是计算机的内存，通常以吉字节（GB）为单位计算。计算机就像人脑一样，每次只能记忆一定数量的信息。计算机执行每项任务时都会占据一定比例的可用RAM，直至任务完成以后才会释放出存储空间。而大多数计算机都会同时执行多项任务，因此RAM空间越大越好。

外存储器

计算机还需要有地方存储所有程序，通常而言，这就是我们称作硬盘的设备。外存储器也以吉字节计算其容量。计算机上外存储器的空间越大，使用者能够保存的照片、电影、音乐等文件也就越多。硬盘是计算机内部的外存储器。而如果你要插入U盘，拷走一些文件，那U盘就称作外存储器了。

普适计算这个术语就是用来描述计算机无处不在的。

输入设备和输出设备

家中的计算机都有一些嵌入其中或附在其外的外部设备，如鼠标、键盘、网络摄像头、打印机。这些都是提供输入、获取输出的工具。举例来说：

·网络摄像头会捕捉你的图像，并传送给正在和你视频聊天的人。这是计算机接受输入的例子。

·你的手指触动键盘、触控板、鼠标，就可以输入信息，给计算机发出指令。

·计算机屏幕能够显示正在使用的网页、文件这些数据，也可以显示游戏页面。此时，计算机提供的显示就是输出。

·一些更新的设备，如智能手机、平板电脑，都是触摸屏幕的。因此，设备的屏幕就既可以输入又可以输出。

·对大多数计算机而言，还存在一种输入途径，即通过USB接口接入其他设备。

网络

无论是使用头戴式耳机无线播放音乐，还是查阅全球范围内其他计算机上拥有的信息，计算机之间通用的对话方式就是网络。计算机连接到家中或办公室的互联网路由器上，就能实现无线网络连接（也就是WiFi）。设备之间还可以通过蓝牙连接，这是另外一种连接方式，可连接诸如无线鼠标、无线耳机等设备。大多数台式计算机拥有以太网接口，可实现物理的、有线的网络连接。

一些微型计算机比如BBC micro：bit（BBC micro：bit是英国广播公司推出的卡片式计算机，主要用于计算机教育。——编者注）和Raspberry Pi（Raspberry Pi也是一种卡片式微型计算机，使用者可将其与电视机或其他显示器相连，再接入键盘，就能用来学习编程。——编者注）也拥有这些组件。这些计算机存储空间很小，可能只够一个程序运行。但就Raspberry Pi而言，你却可以给其中插入足够大的存储卡来扩展空间。

以上这些组件只是计算机的基本组成部分。其他的计算机，比如智能手机，还拥有光线传感器，能自动调整屏幕的亮度；有加速传感器，可以检测手机移动的速度；有陀螺仪，能检测手机偏转的角度；有指南针，能辅助导航；有全球定位系统（GPS），能实现精准定位。

这些额外的传感器，都能在计算机自身情况发生变化时，发挥出相应的功能。

大多数计算机共有的部件和性能包括：负责思考的大脑、辅助大脑思考的内存、存放信息的空间以及接收输入和实现输出的能力。

主板

在计算机内部，有一块较大的板，这块板将前面提到的所有部件连接在一起，我们称其为主板。主板是计算机上所有元件或部件彼此连接的地方，便于电信号在各部件之间来回传输，实现信息的发送和接收。但计算机不是唯一拥有主板的设备，各式各样的设备在电子元件需要连接在一起的时候都会用到主板。

人类计算机

这和人类及其他动物所具备的能力非常相像。我们人类拥有大脑，有记忆，可以思考、储存，还能通过感官系统接收输入，通过肌肉运动进行输出。更不用说，我们每个人的外表看起来是不一样的。

这样来看，你还会说人类和计算机之间有天壤之别吗？假如说微处理器是我们的大脑，那么我们的输入设备是什么呢？

我们可以通过以下方式进行输入：

·用眼睛看东西。

·用耳朵听声音。

·用鼻子闻气味。

·用舌头尝味道。

·用皮肤触摸物品。

我们还有其他获得输入的方法，比如身体失去平衡、头晕眼花时，我们能感知到，饿了、渴了能感觉到，累了也能意识到。

我们能记住很多东西（但是可能不会一次记住所有的东西）。我们也依靠外部储存，比如记日记、拍照片，甚至把东西储存在电脑上。

尽管之前我们提到过计算机的存储容量是以吉字节（GB）来计算的，但实际情况并非总是如此。随着时间的推移，存储器价格越来越便宜，人们会以时下流行的、最经济的可用容量来计量。但就目前而言，吉字节（GB）仍是最常见的存储容量计量单位。比如，在你的电脑上，你可能装了250GB的硬盘和16GB的内存。

这里还有更多关于存储容量的知识：

那么，对比一下，人类大脑的储存容量有多大呢？这个问题多年来一直存在着争议，有些神经系统科学家认为可高达2.5PB，也有神经系统科学家认为只有1TB。对此我们或许永远也得不到一个准确的答案！

你知道吗？

软盘曾经是最为常见的外部存储设备。在互联网和WiFi十分昂贵且未成为主流时，计算机用户就是用软盘传输文件的。因此，在今天大多数计算机的程序中，你仍然能看到软盘的图标，其目的在于方便用户存储文件。

计算机如何工作？

如果说我们的大脑是依靠电脉冲的运动，将信息传递到大脑和身体的各个部位，那么，计算机又是如何工作的呢？这两者极其相似。

二进制

二进制是一种计数方式，只用到两个数字——0和1。我们控制计算机，就是控制计算机内部微小部件（晶体管）的开关，从而引导电流进入正确的方向，实现程序的运行。而掌管着晶体管开关的就是0和1。每一个0或1代表着一个“位”（计算机存储中最小的单位）。

计算机中所有的输入和输出，不论是呈现你最喜爱的电子游戏，还是联网播放有趣的视频，都是由无数个这样的二进制数字组合实现的。这些由多个0和1组成的二进制数字经过翻译，就成为计算机能识别的代码。这种代码就叫作机器码。

你知道吗？

二进制是在167莱布尼茨研发出9年，由德国天才大师来的。事实上，二进制的历史比有证据表明这还要早一些！

二进制运算原理简介

理解二进制较好的一种方式，就是揭示十进制的数字转换为二进制数字的过程。接下来，我们将十进制数字的排放位置以分栏形式表示，先是个位栏，再是十位栏，然后是百位栏，依次排列。从右至左每移动一栏就意味着是前一栏的10倍（这就是我们所熟知的以10为基准的数字体系或者叫十进制体系）：

在上面的图中，2在个位栏，4在十位栏，3在百位栏，即3个100，4个10，2个1，也就是300+40+2=342。

二进制则是由右至左每移动一栏就意味是前一栏的2倍，如下所示：

在上面二进制的图表中，32位栏、8位栏和2位栏中都有1，依次相加32+8+2=42。我们就可以将42这个数字写为101010。

所有的这些1和0就是计算机能懂的语言，即开和关，是和否，真和假。

二进制手指计数法

为了将我们已知的二进制知识展现出来，这里介绍一个有趣的游戏。玩这个游戏只需要运用双手就可以把信息传递给朋友！

就十进制而言，用两只手我们只能数到10，但是如果用手指表示二进制数字，只用一只手就能数到31！请看下面所介绍的方法：

·将拳头攥紧，这代表数字“0”。

·大拇指代表数字“1”。

·食指代表数字“2”。

·中指代表数字“4”。

·无名指代表数字“8”。

·小拇指代表数字“16”。

众所周知，英文字母表中有26个字母，我们要赋予每个字母一个二进制数值，并用手指表示出来。下面的图就为我们展现了如何用手形表示相应的字母。

那么，下面的这组信息拼写出来是什么呢？

‘1000 101 1100 1100 1111 10111 1111 10010 1100 100'

拓展练习

我们使用二进制手指计数法，一只手只能数到31。但如果我们把另一只手加上，就能一直数到1023啦！我们知道，后一根手指的数值是前一根手指的两倍，因此第一只手的小拇指代表数值16的话，另一只手上的大拇指就代表32，食指就代表64，以此类推。

世界上有两种人，懂二进制的人和不懂二进制的人。

这个游戏的答案全是数字（尽管数字不超过1023），你认为自己能够玩这样的游戏吗？你有什么疑问吗？其实，这是个很好玩的游戏，既能锻炼负责创新思维的脑半球，又能锻炼负责逻辑思维的脑半球。

二进制是计算机能懂的数字体系。值得庆幸的是，我们并不需要了解如何使用二进制编程来让代码在计算机上运行。现代编程语言会为我们处理这一切，这些我们随后会加以讨论。现在，我们先来学习计算机和编程的历史，了解计算机和编程发展的历程。

*答案揭晓：‘1000 101 1100 1100 1111 10111 1111 10010 1100 100’拼写出来是‘Hello World’——这是编程学习者最常见的短语和最常使用的练习。

计算机的出现

计算机进入我们的日常生活之前，人们都在做些什么呢？人们怎么会想到创造计算机来为我们执行任务呢？如今，我们可能很难想象一个没有计算机的世界。实际上，计算机的历史远比我们想象的要长得多，我将会在下个小节中详细介绍。

你认为今天的哪些工作可能会被计算机取代呢？

计算机与其他的机器相比有什么不同呢？烤箱是计算机吗？自行车是计算机吗？或许都是！我们先来介绍计算机的定义。计算机广义的定义为能够接收、转换、存储信息，再以设定的形式将信息输出的电子设备。举例来说，电子游戏机通过控制器接收信息，将手指的运动转换为游戏中的指令，然后再将这些信息输出，显示到游戏者观看的屏幕上。再比如智能手表，会通过背面的传感器感应人体脉搏信息，然后将信息输出到手表显示器上。

计算机的出现，如果不是源于新造（如上面提到的游戏机），通常而言，就是为了取代因部件不好使用而时常无法运转的老旧设备。

我们以交通信号灯为例。老一代的机电交通信号灯是由机械开关、齿轮、时钟和杠杆组成的。交通信号灯使用过一段时间之后，就会因为机械生锈、部件磨损以及恶劣天气等因素，出现部件损坏、需要更换的现象。但是不断地维护和修理需要花费大量的人力、财力。相比之下，由计算机控制交通信号灯高效便捷，因此当机控交通信号灯造价降低以后，就逐步取代了老一代的交通信号灯。

利用计算机和网络实现老旧系统现代化的另一个实例就是听音乐的方式。大约30年前，如果你想听音乐专辑却不方便使用立体音响或车载播放器的话，就得买一盒磁带（一盒磁带大约能播放一个小时），再把磁带插入便携式音乐播放机——赫赫有名的随身听。一次只能放入一盘磁带，一面听完之后，得换到另一面才能听完整个专辑（当然再现代一点的播放机就不存在这个问题了）。15年前，第一台便携式音乐播放机出现了，曾骄傲地宣称“将1000首歌曲放入你口袋中”。而今天，在这个互联网接入和移动网络收费不贵、下载可靠的时代，我们可以尽情地让歌曲在设备上“流”（流是指计算机在有效下载文件的同时还可执行文件的能力，能够节省存储空间，此处是指用户在下载音乐的同时就可以播放音乐。——编者注）动，根本不必担心存储空间不够用！

利用计算机复制出所有的功能，而不依赖运转的零件，这在设备的制造、安装和维护中逐渐变得可行。因此，在很多情况下，代码已经取代了过去机械工作的角色。

了解技术的发展潮流，这有利于我们展望未来、预测技术进步将对人类和计算机工作产生的影响。

编程与计算机的历史

与人类历史相比，计算机的历史并不算长。但是编程的悠久历史却可能会令你大吃一惊。如果说二进制出现于17世纪，那么计算机是什么时候发明的呢？又是什么时候出现了程序员呢？以下是计算机历史上重要人物和重大事件的概述，将为我们展现计算机发展的历史轨迹。

查尔斯·巴贝奇（1792-1871）

查尔斯·巴贝奇尽管没有制造出一台计算机，但却被公认为可编程数字计算机之父。在计算器发明之前，人们依靠“人工计算器”进行数学运算。所谓的人工计算器就是人工编制出来的数表，这些数表会印制在书中供人查阅。巴贝奇清楚地知道，在计算时人会疲劳、犯错，因而数表很有可能出现错误。而数表要应用于诸如航海、科学等重要的领域，这些错误是绝对不能允许的。因此，巴贝奇设计了一个通过机械计算机计算数表的系统，他称为分析机。

1991年到2002年，人们根据查尔斯·巴贝奇当时的设计，完成了分析机模型机的制造。如今，分析机模型机就存放在伦敦科学博物馆！

阿达·勒芙蕾丝（1815-1852）

查尔斯·巴贝奇筹建新设备分析机时，阿达·勒芙蕾丝见到了巴贝奇。勒芙蕾丝对巴贝奇的分析机十分着迷，巴贝奇对勒芙蕾丝的科学才能和数学才能也印象深刻，他还戏称勒芙蕾丝为“数字女王”。这台新发明的分析机设计以穿孔卡的方式进行输入，被视为一台可编程的计算机。勒芙蕾丝在当时的工作记录中，描述了一种利用分析机计算伯努利数的算法。要知道伯努利数在数学中非常重要，人工计算有时非常困难、耗时。这个算法被认为是世界上第一个计算机程序，勒芙蕾丝也因此被誉为第一位计算机程序设计师。

阿兰·图灵（1912-1954）

第二次世界大战期间，图灵曾在英国密码破译中心——布莱切利公园工作，以破译德军密码的出色表现声名大噪，而对于现代计算机科学的卓越贡献更是让他百世流芳。不仅如此，图灵还是人工智能领域的先锋，他发明了图灵测试——一种用来检测计算机是否具有足够的智能而能像人类一样通过测试的方法。近年来，通过图灵测试的计算机有深蓝（第一台打败人类国际象棋冠军的计算机）和美国国际商用机器公司的沃森。图灵的工作激励着后人孜孜不倦、不懈努力，在计算机理解人类自然语言及与人类交流的领域不断探究。

蒂姆·伯纳斯·李爵士（1955-）

随着互联网在工作群组和个人间的广泛应用，伯纳斯·李被誉为万维网之父。万维网就是由网页和将网页连接起来的超链接（我们常称为“链接”）两部分组成的。如果1991年他没有发明万维网，我们可能就没法使用互联网、浏览器以及很多当下习惯使用的东西。

戈登·摩尔（1929-）

1965年，摩尔预言集成电路上能被集成的晶体管数目，会以每18个月翻一番的速度稳定增长，并在数十年内保持着这种势头。这一说法就是众所周知的“摩尔定律”，也成为计算机制造商们试图坚守的行业标准。制造商们缩减芯片的尺寸，加大芯片上组件的数量，让计算机体积越来越小、重量越来越轻，功能越来越强大。在过去的半个世纪里，计算机制造的脚步几乎完全遵循着摩尔定律。

试想一下，假如没有这些（以及更多的）从事计算机和编程工作的先驱们，我们的世界将会和现在多么的不一样啊！

人人都能学会编程

编程曾一度高深莫测，被认为是熟练程序员专属的领域，但如今其难度已经大大降低，人人都可以做到。编程的过程既有趣、能表达自我，还具有创造性，是锻炼大脑、培养创造性思维的好方式。看看历史上那些最先学习编程的人，他们就是借助编程解决生活中的问题的，因此你完全不必担心编程不适合自己。不论你是9岁的孩子，还是90岁高龄的老者，都可以学习编程。

此时此刻，你可能会想：假如学习编程，我能做些什么呢？我什么时候才需要编程呢？现在就想展望未来使用编程的美好图景，或者具体用途，可能是有些困难。不过，一旦你开始用编程思维看待世界，未来使用编程的美好图景就会越来越清晰。

学习编程能做些什么呢？

有些要运用编程原理的工作可能还不存在，因此你也许会成为未来某项科技工作的创始人！学习编程也许会让你成为下一个马克·扎克伯格、比尔·盖茨、史蒂夫·沃兹尼亚克（苹果公司联合创始人），这三位知名人物以及其他许多人都运用编程技术创造出了新的事物，而这些技术广为流传，影响了世界各国人民的生活。此外，你或许会希望以编程的方式参与人道主义项目（见第144页），帮助那些生活不富裕、需要技术援助的人们。并且，能够自己编写程序，就能灵活地选择工作地点。只要手边有台电脑，能够联网，就能在世界任意地方工作。

你知道吗？

摩尔斯电码是另一种著名的二进制语言。在19世纪时，摩尔斯电码以电报的形式发送，通过点、画以及点和画之间的停顿来传递文字信息。

世界需要更多的编程者

能够使用互联网是现代美好生活的一个侧面体现，重要的是，我们要学会批判性地思考问题，不能过于依赖搜索引擎。在学习编程的过程中，当你遇到问题时，往往会上网寻求答案。但请一定要慎重，对于来源不明或者不太了解的代码以及其他信息，请一定要谨慎使用。

世界需要更多的创造者，但更重要的是，我们需要这些创造者能制造自己的谋生手段。更不用说，当你的创造能为他人服务时，你就会收获巨大的成就感。人人都可以学习编程，让编程为你服务，不论你是艺术家、公司总裁、板球手，还是科学家。

第二章　解决问题

解决问题

学习编程思维，并不意味着你必须具备多种特殊的技能。不过，拥有解决问题的欲望却非常重要！其实，你一直都在解决问题，只是自己没有意识到而已。

试想一下，你要去一个从未去过的地方，走着走着就迷了路，找不着那个地方了。其实这也不算什么大问题，你可以使用手机导航，可以打个电话找朋友帮忙，也可以查看当地的地图，或者找行人问问路。这些简单的从别处寻求帮助的行为，就是解决问题。

解决问题可能具有挑战性，经常解决问题会使人感到疲惫，但是这对大脑却不见得是件坏事。我们的大脑需要刺激，这些刺激可以使大脑得到锻炼。即使你不习惯每天都要解决很多问题，也可以先从小问题入手，然后再去解决大问题。

定期锻炼大脑、解决问题，不仅仅有益于编写程序或培养编程思维，还有助于集中精力，提高记忆力和反应能力。因此，积极地解决问题，对于每个人而言，都是百利而无一害的。

大脑是怎样工作的？

大脑是由左半脑和右半脑两部分组成的。右半脑控制左侧身体，还负责想象、艺术和创造；而左半脑控制右侧身体，负责逻辑思维、语言学习和推理论证。

大脑的左右两个半球都需要不断地滋养，才能日复一日地执行任务。我们从每日所吃的食物、所喝的水中获取大脑所需的营养，还要通过充足的睡眠保证大脑休养生息。

锻炼身体也是非常重要的。适当地休息休息，伸伸懒腰，到外面呼吸呼吸新鲜空气，都是十分必要的。有时候，快走这样简单的运动，都有可能让你想到一个难题的解决方法。

你还可以做些简单的活动，来锻炼和刺激左、右脑。方法如下表所示：

学习编程很有益处，可以同时锻炼左、右脑——也就是做到所谓的“全脑思维”。

解决复杂的问题

有些问题，打眼一看，觉得非常复杂。如果是这样的话，我们就把大问题分解成小问题，一个一个地理解和解决。接下来，我们就以宇宙为例来说明吧。

我们知道宇宙浩瀚无穷，根据现有的知识，我们可能永远都无法完全理解。准确地说，宇宙是我们知道的最大的事物。但是，如果将宇宙分解成众多较小的部分，比如说先分成银河系，然后再分为太阳系，再进一步分为恒星和行星。这样，我们就能理解这些小的部分是如何构成了较大的整体。

我们并不需要一下子就彻底了解这么大的事物，所以不必因此而感到气馁。大多数复杂的事物之所以复杂，正是因为它们都是由小的、简单的事物构成的。

我们再以同样的思维方式来看化学。为了便于理解构成生命要素的化学物质，科学家们将所有物质的化学成分以及它们的体态分解为元素周期表中的各种元素。于是，通过元素周期表这张微观图，我们就能更好地认识化学物质了。

在生活中，像这样将复杂的体系分解成更小、更易理解的部分，再去了解和解决的事例，你还能再列举一些吗？

脑力训练

有哪些方法可以让大脑活跃起来呢？想象一下，如果自己没做过任何训练就去跑马拉松，结果会怎样呢？同理，不做任何准备，就直接进入解决问题的环节，能行吗？在开始编程或解决问题之前，我们可以采取多种方式使大脑活跃起来。比如，做一做报纸上当日的快速填字游戏，或者试试简单的数独游戏，这些都是活跃大脑的好方法。做完之后，还可以再解一些要运用推理能力的、有娱乐效果的数学或逻辑谜题（见第044～045页）。

数独游戏

数独游戏是近年来非常流行的一种游戏，可以在报纸中、网络上，甚至一些应用软件中找到。在数独游戏中有一个9×9的网格，其中每行、每列都必须由1～9这9个数字组成。这个9×9的网格还进一步分为9个3×3的宫格，每个宫格内也必须由1～9这9个数字组成。

每行、每列、每个宫格中均不能出现重复的数字。数独谜题会给定一些数字，以此引导玩家继续填入其他数字。不过，数独谜题难度等级越高，给定的数字就会越少。

下面就是一道数独谜题：

解决方案：

上面的数独谜题完成后是这样的：

三兄弟

有一种可以同时调动左、右脑的方法，那就是解逻辑谜题。下面有一道逻辑谜题，试试看你能不能解开。这道逻辑谜题来源于著名的逻辑学家、数学家，更是鼎鼎大名的魔术师——雷蒙德·斯穆里安（1919—2017）。

假设你认识长相一模一样的三胞胎，约翰、詹姆斯和威廉。约翰和詹姆斯总是说谎，威廉总说真话。不久前，你借给约翰一大笔钱，他至今没有还给你。有一天，你正在街上走着，碰到了三兄弟中的一人。假若此人是约翰，你自然迫切希望能当面跟他谈谈还钱的事儿。但问题在于你无法辨认此人是约翰、詹姆斯还是威廉。如果只让你问他一个问题来确认此人是不是约翰，你会问什么问题呢？

解决方案：

正确的问题是：“你是詹姆斯吗？”因为约翰是唯一一个会回答“是”的人：

更多逻辑谜题

查尔斯·路特维奇·道奇森（1832—1898）是著名的作家、逻辑学家、数学家，是第一个运用逻辑谜题来帮助人们强化演绎推理能力的人。在三段论的这种谜题中，一般会给定两个或多个假设前提（在谜题中均为真命题），然后从中得出一个推论。

下面是一个广为人知的三段论谜题：

·凡人都会死。

·苏格拉底是人。

·所以，苏格拉底会死。

下面是道奇森的一道逻辑谜题，更加有趣！

·婴儿均无逻辑。

·无逻辑之人受轻视。

·能对付鳄鱼之人不受轻视。

·所以，婴儿不能对付鳄鱼。

你能完成道奇森的另一道三段论推理吗？

·只有接受过良好教育的人才会读《泰晤士报》。

·刺猬都没有阅读能力。

·没有阅读能力的人没有接受过良好的教育。

答案：

正确的推论是：所以，刺猬不会读《泰晤士报》。

其他益智游戏

关于激发大脑思考的谜题，这里再给大家介绍最后一个。这道谜题来自马丁·加德纳，他也是一位数学家、魔术师，他同样因逻辑谜题和数学谜题闻名于世。这最后一道谜题有点“诡异”。

题目要求：将以下字母写在纸上——

N A I S N I E N L G E L T E T W E O R R S D

完成之后，画掉其中的9个，使剩余的字母能够拼成一个单词（A SINGLE WORD）。

解决方案：

NA IS NI EN LG ELTETW EORR SD

N I N E L ET T E R S（九个字母）

你可能会注意到实际画掉的字母数为11个，但这就是“九个字母”，剩下的字母拼成了：A S I N G L E W O R D

其实，脑筋急转弯、字谜以及其他任何激发人思考的游戏都是编程热身的好方式。

约束条件

你可能注意到了，我们在前面的谜题中会受到一些约束条件的限制。约束条件就是游戏中必须遵循的限制条件（或规则）。

例如，在数独游戏中有三项约束条件，即数字1～9在任意行、任意列、任意3×3的宫格里不能出现两次。在这种情况下，约束条件实际上就是游戏规则的一部分。在三兄弟的逻辑谜题中，约束条件为：只能问一句话来确定那个人是不是约翰。

其实，设计约束条件是为了迫使你更为高效地思考。换句话说，就是使用最少的可用资源（此处为语言）来产生最有效的解决方案。在编程的过程中，你可能会受到计算机可用内存的客观限制，需要尽可能地压缩程序，这是在学习编程中经常会遇到的约束条件。

编程以外也有约束条件，如周末要交作业，于是就有时间限制；自己完成报告，其他团队成员才能依据报告继续工作，于是就要求与人合作。

在学习编程的过程中，把你在尝试解决问题时遇到的约束条件记录下来，不要害怕自己会受到其中某些条件的约束。或许有一天，这些约束条件会发挥大作用，让你原本一筹莫展的工作大有起色。

过河谜题

过河谜题广为流传，有很长的历史，可追溯至9世纪，流传至今的一个版本是这样的：

农夫带着恐龙、小妖怪和一箱金子站在河边，准备渡河。农夫要用船将恐龙、小妖怪和金子运过河，但是船不够大，农夫每次只能带一样东西。农夫不能将恐龙单独和小妖怪放在一起（恐龙会吃掉小妖怪），也不能将小妖怪单独和金子放在一起（小妖怪会啃食金子）。那么如何在保证金子、小妖怪和恐龙都完好无损的情况下，把它们都运过河呢？

思考一下，我们过一会儿再回头来看这道谜题。

在这道谜题中，你可能会觉得受到了约束，为何不把农夫、小妖怪和金子都放在恐龙的背上，让恐龙游过去呢？为何不让农夫用金子买一艘大一点儿的船呢？谜题的要求约束了你，不允许你采用这样创造性的方法。

编程时，经常也会遇到约束条件。有些约束来自正使用的计算机，或是硬盘空间不够，或是系统剩余的内存有限，而你所编写程序占用的内存太大。有些约束与时间有关，如编程项目可能需要在两天内完成，于是你就只有大约一天的时间编程，没有足够的时间考虑各种情况。这时候你可能会感到万分沮丧，这完全是可以理解的。不过你还是得找到解决问题的方法，想出最佳的解决方案。

解决方案：

我们再回到过河的谜题中来，你有答案了吗？以下就是解决方案。

·农夫留下恐龙和金子，先将小妖怪运到河对岸。

·农夫返回来，再将恐龙运到河对岸。

·农夫再次返回时将小妖怪带回来，然后把金子运到河对岸。

·最后农夫再返回来将小妖怪运过河，这样农夫、恐龙、小妖怪和金子就都到了河对岸。

你知道吗？

过河谜题已知的最早版本可追溯至公元9世纪！

你可能会考虑到谜题中出现的约束条件：农夫不能将恐龙单独和小妖怪放在一起，也不能将小妖怪单独和金子放在一起。但是你很快会意识到有一个没有约束的条件——一个根本没有告知的条件，那就是你可以往返多次，而且可以将已经运过去的东西再运回来。

从这个谜题中，我们可以得知，解决问题时要关注那些没有给出的条件和信息，因为答案有时就隐藏在看不见的地方。还有一点，做好接受意料之外的事件的准备吧！

编程就是要简单

其实，聪明的并不是计算机！虽然凭借内部的芯片，计算机拥有快速执行多项任务的智能，但是一切智慧的源头还是程序员。因而，每当程序员要让计算机执行任务时，都必须给出十分具体、清晰的指令。

有些编程语言已经具有一些可供使用的内置指令。这些预先编好的指令，我们也称为函数，这个以后还会进行详细介绍。我们先就内置指令做几个一般性的设想：

·计算机能够接收输入并提供输出。计算机接收键盘按键和鼠标移动的信息，然后将结果输出到屏幕、储存设备或者打印机上。

·计算机能够识别数据并加以处理，即计算机可以区分数字、文本以及其他数据类型。

·计算机能够处理变量、逻辑和运算符，完成数学运算。毕竟，计算机完全是依靠数学运算来保证运行的。

·计算机能够辨别方向、标绘路线、在地图上给出位置坐标。

即使计算机具备这样的能力，我们也必须下达十分具体、清晰的指令，计算机才可能完成。换句话说，不能笼统地告诉计算机整理床铺、打扫房间、做三明治，必须清楚地解释所要执行任务的每一项具体步骤。请看一个具体的例子。

清理房间

我们首先必须给整洁的房间下个定义，然后才能确定清理房间的步骤。那么，你认为清理房间这一任务的成功标准（成功标准是指设定一个既定目标以便评估努力是否有效。——编者注）是什么呢？我们只关注三个方面吧。设想一下，假如你要清理房间，你认为最需要做的三件事是什么呢？

如果让我说的话，应该做到以下三件事：

1.整理好床铺。

2.把脏衣服放进洗衣篮里。

3.把所有东西都收起来，放进橱柜里。

假设我自己不清理房间，而是让机器人来做。正好我有一台智能机器人叫“小智”。

我：小智，准备好了吗？

小智：1（表示“准备好了”）。

我：小智，整理床铺！

小智：……（只是坐在那儿）

我：啊，好吧，小智，你应该这样整理床铺。

（1）拉平羽绒被.

（2）将毯子平整地铺在羽绒被上。

（3）将枕头放在毯子的上面。

这就是所谓的指令要具体、清晰。我们现在再来看看如何使指令简单易懂：

1.将羽绒被平整地铺在床上。

2.将床尾一端的毯子折起来，压在羽绒被下面，再从床头一端把毯子拽平。

3.最后，将枕头拿到床头一端，放在毯子的上面。

除此之外，按照正确的顺序执行任务指令，这一点也十分重要。

因此，要达到程序的目的，还必须思考程序中步骤的具体性和顺序性。我们再回过头来，看看清理房间的要求：

1.整理床铺。

2.把脏衣服放进洗衣篮里。

3.把所有东西都收起来，放进橱柜里。

我已经讲清楚了整理床铺任务的成功标准，“小智”得到了明确的指令。如果此时我再告诉他“整理床铺”，结果会怎么样呢？

小智再回到床边，看到铺好的床，一脸茫然。

我：哦！不好意思，小智，床铺已经整理好了。

那么，如果床铺已经整理好了，该怎样让机器人停下来呢？

现在，我们可以借助流程图（又称数据流程图）。流程图不仅用于计算机编程，还可用于谋划各种复杂的事情。流程图能直观地将事件展现出来，它由不同形状的图框和箭头组成：

你知道吗？

编写程序就像是按照食谱做菜一样，每一步的顺序都极为重要，比如，你不能先搅拌了鸡蛋再将鸡蛋壳敲破吧！

·“开始”和“结束”用椭圆形框表示。

·“执行”用方框表示。

·“判断”用菱形框表示。

·箭头表示符号间彼此相连的方式。

下一页的流程图就展示了机器人是否需要整理床铺的判断过程。这个流程图比较简单。而用于商务和软件开发的流程图多种多样，既有像这样简单的，也有更为复杂的。

编程思维就常常要求你离开电脑屏幕，运用其他工具来呈现程序的流程，并与他人进行分享。

第三章　学习编程语言

学习编程语言

编程语言是程序员和计算机之间的桥梁。因为有了编程语言，计算机才会按照程序员的指令做事。还记得吗？计算机只能理解二进制编码（亦称机器码），其表现形式如下：

·0或1。

·是或否。

·开或关。

·真或假。

机器码由数十亿个微指令组成，而这些指令是设计者针对特定的计算机处理器编写的。计算机的处理器不尽相同，机器码也要因计算机的不同而不同，直接编写机器码的任务实在令人畏惧。所以，我们借助编程语言，将人的意图、行动转化为计算机能够识别、执行的代码。

在编程语言发展的过程中，有些编程语言属于“低级”语言。这些语言可以说很贴近处理器，在计算机最底端运行。这样的语言不易理解，程序员只有对程序运行的计算机非常了解，才可能为其编写程序。另一些编程语言，即“高级”语言，是为了方便人们读写而设计的，但是这类语言与处理器之间“千里迢迢”，程序运行所用的时间就要长一些（计算机语言发展经历了机器语言、汇编语言和高级语言三个阶段，机器语言和汇编语言属于低级语言。低级语言是面向机器的，依赖于处理器，编程效率很低，但计算机执行起来效率很高；高级语言接近人类语言，在执行时要经过编译或者解释转换成CPU能够理解的机器码，因而对处理器的依赖减弱，与计算机产生距离，用以编写程序时效率很高，但计算机执行时效率相对较低。——编者注）。不过，当代计算机的运行速度已经很快，因此我们不必担心这个问题了。在学习编程的过程中，你现在能遇到的大概都是高级编程语言。

接下来，我们会介绍一些在大多编程语言中都会用到的概念和术语。我们都知道，学习任何新的语言，都会碰到全新的规则和陌生的术语，请切勿因此泄气哦！

你知道吗？

计算机编程语言名目众多，数不胜数。倘若把计算机编程比作一个国家，那么这个国家一定是世界上语言最繁多、最复杂的国家。

编程语言的语法规则

你以前肯定接触过“语法”这个词吧？每种语言都有语法，编程语言也不例外。

语法界定了字母、单词、标点符号以及短语的排列规则，能帮助我们正确地表达与理解语句。请看下面两个例句：

“我们吃，小智！”

“我们吃小智！”

如上所示，一个逗号之差完全改变了整个句子的语境！有时，我们在不经意间给代码中加入或减掉一个字符（如上文的逗号），就会引发完全意想不到的结果。

不论你讲的是哪种语言，肯定都知道语言中的字词排列是有一定顺序的，是遵照一定规则的，编程语言也不例外。在日常生活中，我们谈话、写作时，会把字词连贯成句表达意思。每一种语言，无论口语还是书面语，都有其自身的规则。当我们用不同语言表达英语中的“Hello world”时，我们就可以看到其结构上的变化。

编写代码时，我们会用到语句。语句是代码中能够引发一个动作的最小单位。举例来说，我们要让计算机屏幕上显示“Hello world”的字样，不同的编程语言，就会用不同的语句告诉计算机如何执行：

从这样一个简单的程序中，我们就能看出，几种现代编程语言的语法规则存在明显的差别。在Python语言中，括号（）、引号“”的使用与其位置在编程中至关重要。在Ruby语言中，特殊格式的要求很少。而在Java语言中括号和分号所处的位置很关键。另外，Python语言和Java语言都要求代码行正确地缩进，英文字母大小写的正确书写在编程语言的语法中也很重要。这些语法规则就是为了确保指令书写正确，便于计算机正确识别。

语法和语境

语法至关重要，不仅规范了我们自己书写代码的方式，也限定了用户使用时的交流方式。近几年兴起的手机虚拟助手就是一个极好的例子。虚拟助手已经颠覆性地改变了我们运用技术的方式，如今我们可以使用自然语言——语音，与计算机进行交流。

与虚拟助手对话是一种特别的体验，既要用到语法，还需要用到语境。假如你想用手机虚拟助手查看周围电影院播映的电影，你就可以简单地提问：“语音助手，附近影院播映的电影有哪些？”然后就能得到准确的答案。你甚至还可以用口头语问：“今晚电影院都有什么电影？”“告诉我附近影院放什么电影？”也会得到相同的结果。不过，人们不常使用的、过时的语言可不一定能达到这样的效果，比如说：“劳烦告知今夜观影剧场详址。”

毋庸置疑，虚拟助手后台的程序员尝试着预测并使用多种可能的方式和用户进行沟通。所以，编程思维还包括程序使用者的思维！

改变一个字母，改变整个意思

请观察以下语句，看看增减一个字母甚至一个标点符号会如何彻底改变语句的含义。

‘Please exist through the gift shop.'（请穿过礼品店存在。）

‘Most of the time travelers worry about their luggage.'（大多数时间旅行者都操心他们的行李。）

你能想到其他的例子吗？

答案揭晓：

‘Please exit through the gift shop.'（“请穿过礼品店离开（exit）。”）

‘Most of the time, travelers worry about their luggage.'（“大多数时间，旅行者都操心他们的行李。”）

集成开发环境

集成开发环境（IDE）能为程序设计者编程提供极大的帮助。集成开发环境是一个软件工具，可以在编写代码时使用。

现代的IDE具备语法高亮显示功能，能在编写代码时为你做出指导。语法高亮显示功能会更改语句中字符的颜色，方便迅速识别字符的身份，比如，是函数，还是字符串或是其他（这些以后还会再讲）？

IDE的另一个特点就是可以自动补全，能帮助你完成语句书写，还不会出现错误。

有些IDE软件有内置的参考资料，比如一些编程语言库，方便你在编程时查阅术语的含义。有些IDE软件是非常简单的文本编辑器（如Atom），设计的目的在于能为多种语言所使用。而有些IDE软件用途专一，比如Greenfoot只用于Java的编程，XCode专为苹果电脑服务，用于制作应用程序。所以，你的选择空间其实很大，就像工作中挑选最好使用的工具一样，你可以挑选一个最适合自己的IDE软件。在学习编程的过程中，你会得到很多帮助，甚至有来自软件工具的帮助。

编程的形式

自从计算机编程诞生以来，已经被设计出来的编程语言就有100多种，当然，并非所有的语言现在都在使用！在一段时期内，因为语言用途的缘故，也就只有10～15种比较流行的编程语言被经常使用。

我们在使用编程语言时，还要考虑是使用解释型语言还是编译型语言。

使用解释型语言时，所创建的程序不需要再做任何处理，就可以在不同的计算机上运行。创建的程序可以在其他计算机上直接打开、运行，并如最初设计的一样进行交流。一个常见的例子，就是我们使用万维网浏览网页。网站服务器推出精彩的网页或者游戏，供全球数万人赏玩，用户们体验相同，甚至能够一起玩游戏（如风靡全球的网站游戏slither.io蛇蛇大作战）。在这个过程中，除了浏览器以外，用户不需要安装或下载任何东西。

使用编译型语言，即表示程序或应用程序必须放进一个单独的文件（或可执行文件）中，而此文件只能在特定的设备上运行。比如，你不能直接把笔记本电脑上喜爱的应用程序放入手机中运行。如果想在手机上使用，那就得安装一个不同的程序编译版本。这些程序、应用软件的新版本很多时候都需要在手机上重新编译和安装，比如，在应用商店下载更新时，应用程序打补丁修复时，都是这样的。

在下文中，我还会换一种方式说明解释型语言和编译型语言。

假期，狐猴相伴！

假设今年夏天，你在马达加斯加度过了一个愉快的假期，研究狐猴并作画写生。每天都有一只狐猴来到你跟前，做着相同的姿势，等着你以它作画。没过多久，你便成了画这只狐猴的顶级专家。你给这只狐猴取名丹特。当你要离开的时候，丹特也收拾行李和你一起回国。

回家之后，家人、朋友、同事都想要你画的狐猴画。因此你打算用最好的纸和笔画一幅“大师级”的狐猴画，然后将其彩印出来送给家人、朋友。最后，大家都拿到了同样的（解释型的）狐猴画。

精彩的狐猴画因此广得赞誉，大受赞赏。一位艺术与自然杂志的编辑从远方打来电话，希望能在下期杂志中刊登你的画作。编辑已经有了画作的复印件，但是其格式与网站要推出的格式不符。此外，编辑还需要一个放大比例的版本，用于制作大型广告牌。

在与杂志方交流之后，你得知了画作用于广告宣传所需要的技术规格，并与艺术学院的朋友取得了联系。朋友有一台手绘屏电脑，并愿意借给你创作“电子版”的狐猴画。

你画了三种不同尺寸的狐猴画，最大的画用于广告牌，中等的画用于杂志刊登，小规格的画用于网站。于是，你发给了编辑。这就是三个具体编译的版本啦（其实只是一幅狐猴画）！

其他类型的编程语言还有面向对象语言、数据语言、脚本语言。如果你打算学习编程语言，并准备从诸如Java语言、Python语言等常见的语言入手，那么你一定会用到面向对象程序设计。

面向对象程序设计（OOP）

运用面向对象语言编程就意味着要创建对象。而此对象并非实实在在的可以用手触碰的物体，而是软件中虚拟的物体。这些对象可以完成一定的任务，能和程序中其他部分实现互动。接下来，我们使用面向对象语言创建一个虚拟的物体，来看看我们和虚拟物体之间的差别与相似之处。

运用面向对象的程序设计，我们如何创建一只狐猴丹特呢？首先，注意观察丹特的特征。丹特是黑色皮毛、橙色眼睛，喜欢爬树、吃东西、为绘画者摆姿势。

按照面向对象的程序设计，我们应先从对象的类别开始。类就是创建一个能够反复多次使用的蓝本。要创建狐猴“丹特”这个对象，我们得先创建一个狐猴的类。在狐猴类（或蓝本）中，除非我们为其加上某些典型特征，否则所有的对象将会一模一样。

我们来创建一个名为丹特的对象：

丹特可以做一些事情，称作行为（或方法）：

我们创建了一个类、一个对象及其属性和行为。初步完成之后，我们发现丹特饿了，所以最好再创建一些食物给它吃。我们先创建一个称为食物的类：

我们把狐猴的食物这一新对象放在丹特面前，丹特想去吃食物，但是不知为什么却吃不到。不管多么卖力，丹特还是吃不到食物。啊！原来是我们没给狐猴的食物赋予方法！

在给狐猴的食物赋予方法（狐猴吃食物）之后，狐猴终于可以吃饭啦。

每创建一个对象都要为其赋予方法，这些对象才能够相互作用。比如，我们将一个对象命名为“汽车”，这可不意味着它就可以直接开走。

我们再来看一个例子。我们知道丹特喜欢在别人作画时摆姿势，那我们就再创建一些对象来画丹特。首先，创建一个人的类（在此例中，我们假设人这一类中所有的对象都有胳膊、腿等，而且能做人所能做的事情）。其次，再创建一些画丹特需要的工具。

注意到了吗？我们在创建铅笔这个对象时，特别强调了是绘画铅笔。如果你去一家文具店仔细看看，你就会留意到那里的钢笔、圆珠笔、铅笔各式各样、用途迥异，有些区别于颜色，有些区别于笔尖，有些专为写作，有些专为绘画。因此，我们在铅笔类中创建了“绘画铅笔”这一对象。

我们在创建“你”这一对象时只提到两个属性，即“你”拥有双手和手指。毫无疑问，“你”作为人拥有的属性远不止这些。然而在OOP中界定对象时，我们只提及相关性最强的属性。设想一下，假如在此场景中“你”的头发为棕色，穿着红色T恤，这有什么关系吗？“你”握笔的不同手势，又能产生什么影响呢？

我们再将目光投入到家中。假设“你”的家里有好几台电视机，比如说楼上有一台，楼下有一台。“你”也会有两个遥控器，一个楼上的遥控器，一个楼下的遥控器。这两个遥控器都具备一个属性，就是需要安装电池。那么，两个遥控器又具备哪些功能（方法）呢？能换台吗？能放大音量吗？任何人都能够使用吗？

不同的数据类型

凡是进入电脑的信息，不论是图片、文本、数字还是其他的形式，最后都是由1和0组成的。就像在动物王国里给动物分类，我们也可以在编写计算机程序时为不同的数据分类。其实这么做是有原因的，因为只有这样计算机处理信息时才不至于无从下手，才可以根据我们提供的信息进行相应的处理。

能够确定和描述我们要使用的数据类型，对于编程语言理解数据的最终使用目的、数据存储的方式以及数据代表的意义都极为有用。这一实例也进一步说明，计算机无法理解人类的用意，除非我们明明白白地告诉它。

如果我告诉你我要给tank加油，你会想到什么样的画面呢？再比方说我要把bat弄走呢？你可能会想到，我要把汽车油箱（tank）加满，把运动器材球拍（bat）放到一边，但你可能想不到，我在给一辆坦克（tank）加油，要把一只小蝙蝠（bat）赶走（正巧它在板球上玩呢！）。

计算机无法理解同形同音异义词（发音和拼写都一样，但含义不同的词），也无法区别阿拉伯数字“2”和汉字“二”。因此，我们要以数据类型划分各种数据，以便于计算机能够理解和处理。

那么，都存在哪些数据类型呢？

字符串（也称为文本类型）

字符串是指有序的字符序列。字符是计算机可以显示的任意符号，包括字母、下画线和数字。字符串可以很短，只有一个字，也可以很长，由多个字组成，像一个句子那样。

比如，词语“字符串”是一个字符串，而句子“那是字符串！”也是一个字符串。

字符串（文本类型）也可以包含数字（因为数字也是字符，所以数字也可以是一个字符串）。编码之前你可能会对此困惑不解，不过，开始编码以后你就了解了。想一想，给出一些你想要变成字符串的数字（数字变为字符串就不能进行普通的运算了）。想一想你的电话号码或邮政编码？这些数字你肯定不会拿来进行加减乘除等运算。所以这些数字正确的输入方式就是以文本的形式输入。我们都知道在许多地方，电话号码以数字0开头，如果电话号码被存为数字类型，那么0就会从电话号码中给去掉了。

数值型

我们都知道数字不止一种特定的类型，编码同样如此。

首先有整数类型。整数类型就是指整数，如从0到10的数字。人的年龄就是整数的例子（例如，她12岁）。整数有正负值，但不包含小数。小数属于实数或浮点数，例如0.5、7.2和10.315等。浮点类型的数字也有正负值。实数（或浮点数）的例子包括纬度和经度（如4°8′15″、162°3′42″）、温度（37.5℃）。

布尔型

布尔型类似于二进制，只有两个状态：真和假。二进制计数系统只使用1和0，只能表示两种状态，即开或关。我们同样也可以使用其他意义相反的词语进行描述，如上和下，正和负，进和出。布尔数据类型只用于回答有两种答案（是或否）的问题。

日期和时间类型

日期/时间数据类型可存储日期和时间值。这种数据类型看似简单，然而不同的国家却有着不同的日期表示方式。

如果我们以2015年10月21日为例，在美国通常表示为10/21/2015（月/日/年），而在英国则表示为21/10/2015（日/月/年）。日期/时间数据类型就是要确保大家谈论的是同一日期。

数据类型的选择及使用会影响到数据的显示格式。例如，你不能输入日期42/13/5446（至少在地球上不可以啊！）。

二进制大对象

BLOB表示二进制大对象，代表大的多媒体文件，如图像、音乐或视频文件。

有些编程语言和数据语言会对数据类型做进一步的细分。例如，SQL（结构化查询语言）是为访问和使用数据库而设计的语言，不仅有表示年、月、日值的日期数据类型，还有存储时、分、秒值的时间数据类型以及存储年、月、日、时、分、秒值的时间戳数据类型。

数据结构

我们划分了不同的数据类型，但有时仍需设法整理数据并确保其有序性，以便高效利用数据。在学习“二进制手指计数法”时，每一个手势都指代一个数字，并与字母表中的一个字母相匹配（见第022～024页）。正是因为有了这种匹配结构，我们才能够了解手指二进制中每个手势的含义。

算法

算法一词可能并不常见，听起来也有些不好懂。算法其实就是为了完成某项特定的任务而要按照既定顺序执行的一系列明确的指令。我们在“编程就是要简单”一节中曾经做过简单的探讨，当时就是给“小智”制订了一套明确的整理床铺的指令（见第056～062页）。

算法中指令越具体、越明确，指令运行时出现错误的概率就越小。算法就像是做菜使用的“食谱”，是计算机所要执行的命令。我们来试一下，给小智发出指令，让它为我们做个加奶酪的三明治：

1.拿起一片面包。

2.将面包放在厨房的操作台上。

3.把黄油盒的盖子打开。

4.把盖子放下。

5.握住手柄拿起刮取黄油的小刀。

6.一只手握住小刀的手柄，让刀口向外。

7.放低小刀并在黄油上刮取三秒钟。

8.拿起小刀。

9.使小刀靠近面包片。

10.放低小刀，在面包片上涂抹三秒钟，一共涂抹两次。

我们已经完成了10个步骤，却只给面包片的一面涂上了黄油！

11.把小刀放在操作台上。

12.拿起一片奶酪。

13.把奶酪片放在涂有黄油的面包片上。

14.再拿起一片面包。

15.将其覆盖在奶酪和有黄油的面包片上。

你是否留意到，上面的指令非常具体，甚至提到了如何握刀？其实我们还可以更加具体，描述使用小刀时的角度及涂抹黄油时小刀的速度。在第7步和第10步中，我们的描述还包括计算机要取、涂黄油的时间。毕竟，小智不知道刀上的黄油有多少算够了，面包怎样才算抹好了。因此，我们做出估算，大概需要三秒钟的时间。

单步调试

西方有句古老的谚语，“量两次，裁一刀”。其本质意义是说，干活时多核查要比出了问题后返回来弥补更有效率。对于编程的初学者而言，这应该成为不成文的规则。检查算法时，应该单步调试（一步一步检查代码的过程。——编者注）、逐步进行，确保其合理规范。

我们再来看另一个关于算法的例子。这是一个游戏，需要用些数学知识，来猜测人的年龄。

猜年龄游戏

在这个“数学魔术”的戏法中，你可以先告诉朋友，你不用他们说就能猜出他们的年龄。游戏具体如下：

1.让你的朋友在一页纸上写下他的年龄。

2.将这个数字乘以2。

3.再加上1。

4.然后乘以5。

5.再加上5。

6.再乘以10。

7.再减掉100。

8.最后再画掉末尾两位数。

最后剩下的数字就是他的年龄，一共只用了简单的八个步骤。

循环

讲到这里，好像我们要做很多具体的事情，特别是介绍算法编写时，有些东西不仅烦琐而且还有重复。我们知道编程语言设计的初衷就是为了便捷高效，那么一定有方法能避免重复指令的书写。

可喜的是，“循环”就能解决这一问题。循环就是能够使重复指令的编写变得更为高效的结构。你之前一定遇见过循环。地球绕着太阳转就是每年你所参与的最大的循环，每365天重复一次。而比这小一点的循环呢？地球每24小时自转一周。循环无所不在，只要事物重复，就有循环存在。

我们来用“循环”处理一些基础的指令，使其变得简单一些。

假设你站在距离我10步远的地方，我想让你走过来，我可能会说：

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

“向我走1步”

结果，我会因为发布了这么多条指令而筋疲力尽，而你一下子听到10次相同的要求，可能也会特别烦。

还可能出现一种情形，那就是我给你的是书面指令，而我不小心把数字打多了，让你“向我走13步”（这句指令尽管语言有误，但还是可以执行的）！

你可能已经猜到，较好的解决方案就是我告诉你：

“向我走10步。”

这就用到了循环。循环就是执行重复指令，直至过程结束的一种结构。循环分为两种：以次数控制的计数循环和以环境控制的条件循环（条件循环将会在第096～100页中做详细介绍）。

for循环

通过计数控制的循环，叫for循环。for循环会多次重复指令，不管结果如何。比如说，在我叫你“向我走10步”的时候，你我之间可能隔着一堵砖墙，但如果你真要严格执行我的指令，那是不可能阻止你向我走来的。你可能中途被砖墙给挡住了，但你已经正确地执行了我的指令。

while循环

while循环属于条件循环，是通过循环的条件来控制循环次数的。在满足条件之前，循环会持续运行。假设我告诉你：

“向前走，一直走到我身边。”

这次的情形和上面让你向我走10步的情形不同，你可能得花点时间绕墙啦！

我们再想想前面做奶酪三明治的算法，是不是只给一片面包涂抹黄油就花了不少功夫？如果能够运用循环，那效率是不是会提高很多呢？

做个升级版的奶酪三明治

1.拿起一片面包。

2.将面包放在厨房的操作台上。

3.把黄油盒的盖子打开。

4.把盖子放下。

5.握住手柄拿起刮取黄油的小刀。

6.一只手握住小刀的手柄，让刀口向外。

7.放低小刀并在黄油上刮取三秒钟。

8.拿起小刀。

9.使小刀靠近面包片。

10.放低小刀，在面包片上涂抹三秒钟，一共涂抹两次。

11.重复以上1～10步。

注意到了吗？我们只要多加一条指令，就能省下不少时间，也能使奶酪三明治的口感更好。这样我们就完善了算法的前半部分，那么对后半部分还需要做些什么吗？

12.把小刀放在操作台上。

13.拿起一片奶酪。

14.把奶酪片放在涂有黄油的两片面包片中的一片上。

15.再拿来另一片涂有黄油的面包片。

16.将其覆盖在有奶酪的面包片上。

在算法中，我们必须修改一个步骤，来处理另外一片已经抹有黄油的面包片。这样，把循环引入算法中，通过修改一个语句几乎就能完成双倍的编程工作！

或许你已经意识到了，我们把循环加进算法以后，又出现了新的问题。我们没有为制作三明治的程序发布停止重复1～10步的指令！要知道计算机可是完全按照你的指令行事的。步骤11出现了无限循环——这是一定要避免的。按照我们书写的算法，计算机会一直为面包片涂抹黄油，直到没有面包片可用，最后程序崩溃，这样就糟糕了。因此我们必须对程序进行修补，我们可以为步骤11做如下修改：

11.重复以上1～10步，给两片面包片涂完黄油终止。

这样，在算法中，我们就为循环在其完成之前加上了一个特定的条件。现在，我们可以品尝美味的（也是制作高效的）奶酪三明治了。

其他循环

以下是一款流行的扑克牌游戏，你能从游戏说明中找到循环吗？

“钓鱼”游戏规则

参与游戏人数：2～6人

游戏目标：集齐尽可能多的“册牌”。一册牌即为牌面数字相同花色不同的四张牌（如四个A、四个2）。

1.给每位玩家发五张牌（若只有两三位玩家，则每人发七张牌）。然后把剩下的牌牌面朝下放在中间，成为“池塘”。

2.从发牌者左边的人开始，为第一位玩家，他可以根据手中的牌向另一位玩家要一张牌，要的这张牌一定要和自己手中至少一张牌数字相同，不可以要（或者钓）一张和自己手中牌面数字不同的牌。

3.如果那位玩家手中有被要的牌，则必须交给这位要牌的玩家。

4.成功之后，这位玩家再继续问其他玩家要牌。

5.如果被要牌的玩家手中没有这位玩家所要的牌，他就告诉这位玩家“去钓鱼吧”。于是这位玩家就从中间的池塘中拿出一张牌。然后，就轮到下一位玩家来要牌。

6.一旦玩家手中有四张数字相同花色不同的牌（一册牌），玩家就拿出来，放在自己的面前。

7.如果玩家手中一张牌也没有了，就从池塘中拿一张。

8.当池塘中没有牌时游戏结束，拥有册牌多者获胜。

在步骤1中，发牌者给每位玩家轮番发牌时，我们就可以看到第一个循环（循环1）。“先给第一位玩家发一张牌，再给第二位玩家发一张牌，再给第三位玩家……”你可以想象如果指令是这样的，该有多么无聊！其实，只需一个指令，发牌者就会不断发牌，最多可以发出30张，最少可以发出14张。

接着，游戏开始以后，在步骤2中又是一个循环（循环2）。

一位玩家向其他玩家要牌，直至要不到牌的这个过程又是一个循环（循环3）。

游戏结束后，循环1才最终结束。

条件语句

条件语句（亦称条件）很简单，是计算机根据给定的信息做出选择的语句，我们在循环中已经见过。生活中，我们每天所做出的决定，都要考虑条件。关于这一点，可以想想不同的天气对穿衣的影响。请看下面的例子：

如果外面在下雨，

那么我就需要带把伞出门。

如果人行道信号灯是绿色，

那么我就可以安全地穿过马路。

如果手机充电完毕，

那么我就可以拔掉充电器。

条件语句通常以“if（如果）”开头，比如：“if发生那种情况，then（那么就）做这件事”。我们还可以在条件语句中增加else（否则，要不然），来表示更进一步的选择和具体的情况。比如：

if外面在下雨，

then我就需要带把伞出门。

else（要不然）

我就穿件外套出门。

if人行道信号灯是绿色，

then我就可以安全地穿过马路。

else

我就可能会受伤。

if手机正在充电，

then我就让手机继续充电。

else

出门时手机电量就不满。

还记得吗？我们在“编程就是要简单”一节中设计了让小智整理床铺的流程图（见第062页），已经学过了使用条件语句。

在流程图中，小智整理床铺时要检查一些条件是否具备。如果条件不具备，小智就要完成这个步骤，然后进行下一步。我们可以将小智的动作步骤用条件语句表达出来：

if羽绒被不平整，

then拉平羽绒被。

else

进行下一步。

if枕头不在毯子的上面，

then把枕头放在毯子上面。

else

结束。

我们还可以通过给羽绒被、毯子和枕头的状态赋予布尔值进一步简化程序。

if羽绒被拉平了=真，

进行下一个步骤。

else if羽绒被拉平了=假，

拉平羽绒被。

if枕头放在毯子上面=真，

进行下一个步骤。

else if枕头放在毯子上面=假，

把枕头放在毯子上面。

结束。

关于小智整理床铺的算法，在以下最后一个版本中，我们将以事件的真假作为语句的条件。“‘羽绒被拉平了’=假”就相当于“‘羽绒被不平整’=真”，我们上面编写的算法将羽绒被、毯子和枕头的真假值全部考虑到了。但是，只有当条件为假时，我们才需要小智采取行动，即只有当床铺没铺好的情况下，我们才需要小智行动，反之则不需要。就整理床铺而言，以下还有一种算法表达形式，更为简单：

if羽绒被拉平了=假，

拉平羽绒被。

else

进行下一个步骤。

if毯子拉平了=假，

拉平毯子。

else

进行下一个步骤。

if枕头放在毯子上面=假，

将枕头放在毯子上面。

else

结束。

以上后两个算法均正确，你认为哪一个更为高效呢？两个算法均占八行，你能说一个比另一个更高效吗？请别忘记，高效不仅在于所占行数更少，更在于每一个步骤都有意义。

其实，在倒数第二个例子中，我们完全不需要加入“if羽绒被拉平了=真”这一条件。因为我们已经将其包含在内了：if羽绒被不平整，将羽绒被拉平。if情况反之，则进行下一步。也就是说，else语句就将“真”的情况考虑在内了。

正如古老的谚语所说，质量（此处指意义。——编者注）第一，数量第二。

“钓鱼”游戏的更多条件

我们再来看看“钓鱼”游戏。如果回顾游戏规则，你会发现游戏当中有不少条件句。条件句找起来并不难，通常以“if（如果）”开头。你能把条件句全都找出来吗？

（带条件的）“钓鱼”游戏规则

1.给每位玩家发五张牌（若只有两三位玩家，则每人发七张牌）。然后把剩下的牌牌面朝下放在中间，成为“池塘”。

读完游戏规则的第一条，我们就可以看到第一个条件语句：

if游戏人数小于等于三且大于一，

then给每位玩家发七张牌。

我们再来看第二条规则：

2.从发牌者左边的人开始，为第一位玩家，他可以根据手中的牌向另一位玩家要一张牌，要的这张牌一定要和自己手中至少一张牌数字相同，不可以要（或者钓）一张和自己手中牌面数字不同的牌。

在这一步骤中也出现了条件语句：

if这位玩家手中没有某个数字的牌，

then这位玩家不能要此数字的牌。

3.如果被要牌的那位玩家手中有被要的牌，则必须交给这位要牌的玩家。

步骤3中的句子就是现成的条件语句啦！

4.成功之后，这位玩家再继续问其他玩家要牌。

5.如果被要牌的玩家手中没有要牌的这位玩家所要的牌，他就告诉这位玩家“去钓鱼吧”。于是这位玩家就从中间的“池塘”中拿出一张牌。然后，就轮到下一位玩家来要牌。

在步骤5中，条件句有三个后续的动作。

if被要牌的玩家手中有所要的牌=假，

then被要牌的玩家就告诉要牌的玩家“去钓鱼吧”。

要牌的玩家就从池塘中拿一张牌。

此轮结束。

6.一旦玩家手中有四张数值相同花色不同的牌（一册牌），玩家就拿出来，放在自己的面前。

在步骤6中出现了有if的条件句！

if玩家手中有一册牌，

then就从手里拿出来。

7.如果玩家手中一张牌也没有了，就从池塘中拿一张。

下面又是一个思路清晰的条件语句：

if玩家手中的牌数=0，

then玩家从池塘中拿一张牌。

8.当池塘中没有牌时游戏结束。拥有册牌多者获胜。

步骤8中的条件语句：

if池塘中的牌数=0，

then游戏结束。

if玩家A比玩家B拥有的牌册数多，

then玩家A获胜。

else if玩家B比玩家A拥有的牌册数多，

then玩家B获胜。

请注意，“拥有册牌多者获胜”这一表达要求我们对胜出和失败的情况给予详细的指令描述。

“钓鱼”这款简单的扑克牌游戏，有着易学易用的游戏规则与玩法。同时，这个游戏也告诉我们，任何事物都可以用编程思维的方式进行思考！

流畅的运算符

你可能留意到了，我们在扑克牌游戏的条件语句当中使用了一些符号，这些符号正是判断（或者叫比较）运算符。或许你会怀疑两个等号放在一起是否有误——这可不是打字错误。

我们会运用条件句判断真假，而运算符则能帮助判断真与假。下表列出了一些比较运算符及其意义：

我们在编码中要把值和意义赋予我们称为变量的事物时，还会用到等号（=），后面章节中会介绍（见第118页）。

逻辑运算符

在前面的例子中，比较运算符并不是唯一涉及的运算符。逻辑运算符也可以在条件句中使用。逻辑，还记得吗？我们在“脑力训练”一节为大脑热身时（第043页）就有过接触。

以下是一些逻辑运算符及其意义：

我们已经掌握了比较运算符和逻辑运算符，那么游戏规则的第一条说明应该如何表达呢？

if游戏人数小于等于三且大于一，

then给每位玩家发七张牌。

如果再简单一些呢？

解决方案：

if游戏人数＜=3&&＞1，

then给每位玩家发七张牌。

不可思议的铜币！

以下是一个魔术戏法，我们将用条件语句判定被拿起的硬币到底是哪一个。玩这个戏法需要五枚铜币、一张桌子，还要有一个朋友参与。

游戏过程：

首先，将五枚铜币放在桌子上。然后告诉你的朋友，“在金钱方面，我有一项特殊的能力。这项能力只对小面额的硬币有效，因此很少对人提及。而你是我最好的朋友，我不妨给你展示一下。”

或者，说一些类似的话。朋友点头之后，你继续说：“请看桌子上这五枚铜币，可以随意检查并移动铜币的位置。”朋友照做之后，再告诉他：“现在，我转过身去，你选择一枚铜币，将它贴在你的额头上。”

朋友从桌上拿起铜币之后，告诉他要紧紧地贴在额头上，并竭尽全力去想着这枚铜币，这样他就能把心里的信息通过铜币传递给你。持续半分钟之后，让朋友把铜币放回到桌上原来的位置。

朋友完成之后，跟他说：“嗯，心灵的讯息已经传送完毕啦！我现在要把手放在铜币上逐一分辨，找出有心灵感应的那枚铜币。”

当你把手靠近桌上的铜币时，你就能感受到那枚在朋友额头上放了半分钟的铜币正散发着余热呢。这时，你拿起这枚铜币，朋友一定会惊讶万分。

你能发现这个魔术中的条件语句吗？

if一枚铜币是热的，

then这枚铜币就是朋友拿走的那一枚。

如果你知道寻找条件语句的方法，就能在生活中很多地方找到它！

趣味函数

编程时，我们不需要将程序一点一点地全部写出来，有些部分计算机会帮你完成，这就是函数的作用。

简而言之，函数就是一种编程语言中已经写好、可供使用的代码。这些语句已经编写在一起等你使用，这就是常说的内置函数。

内置函数因编程语言的不同而有所差异，但其存在的意义在于避免程序员做重复的工作。

进行基础或复杂的数学运算，生成随机数，在屏幕上显示文本，这些都是内置函数应用的实例。有了前人辛苦工作的成果——函数，我们就不需要再花时间重复别人已经做过的事情了。

以下是Python语言中的三个常见的内置函数：

在上面Python语言的函数中，我们可以看出括号（）里面的内容为空。其实，括号中是等待我们放入参数的。在函数中，参数为函数提供具体输入的信息（自变量，在第118～128页将做详细介绍）。我们之前在学习语法规则时也见过print（）函数，如下所示：

print（“Hello world”）

因此我们为函数所提供的参数（输入信息）即成为函数的输出信息。在print（）函数中，输入信息为参数‘Hello world’，因而计算机屏幕上输出的就是：

Hello world

这看起来很棒，是不是？还有更棒的。你还可以自己定义函数，完全不必只依靠编程语言中的内置函数。因而，假如在编码中你会多次用到同一个算法，不妨将其保存为一个函数，方便多次反复使用。

近观函数

函数就是事物内部自动运行的活动。这个定义不仅适用于计算机。如果观察一下人体，我们很容易就能发现人体运行系统中“提前置入”的常用函数。这些函数融入人体、自动运行，大多数时候我们甚至不会察觉它的存在。比如说，你什么时候观察过自己的呼吸？

我们就来花点时间，观察一下我们呼吸的过程：吸气和呼气。呼吸是身体至关重要的函数，没有呼吸，我们就无法让氧气进入血液，并输送到身体的各个器官中去。

如果我们可以进入大脑，看到身体内在的运行系统，就会发现两个函数：吸入函数和呼出函数，正在进行着无限的循环。这是什么样的情形呢？

这些就是人体中“内置”的算法和循环！

在编程语言中，有一点极为重要，即内置函数并非一直都在那里，当你需要使用的时候它才会出现。这就是高效的实例——只引入需要使用的函数。假如在编码中我们把所有可用的函数都囊括进来，那么代码将会繁杂、臃肿不堪。

如果我要用到与时间、数学计算相关的函数，我就可以从编程语言中“借用”（或引入），然后就能在编码中进行各种相关的数学运算了。

我曾经仔细观察，发现我的肺部并不知道如何进行数学计算（至少，我认为肺部不懂数学运算）。可是假如我想计算吸气和呼气需要多长时间，或者想让呼吸变慢一点，那就必须用到数学计算。在人体运行系统中，我会从身体的另一部分——大脑中引入数学函数并进行使用。

魔力8球

魔力8球发明于20世纪50年代的美国，是一种持于手中的小玩意，传说能预知未来。球体内部装有蓝色液体，漂浮于其中的是一个20面体，每一面都印有不同的答案。要使用魔力8球的人会问一个简单的问题，得到是或否的答案（就像布尔值一样），然后翻转球体，这时20面体就会有一面漂浮在上，球体背面的窗口就会显示出答案了。

魔力8球上的答案分为是、或许、否三类，具体如下：

在20种可供选择的答案中，有10种是“肯定”的答案，5种是“否定”的答案，5种是“或许”的答案。

如果我们只有铅笔、纸和几个骰子，要设计一个魔力8球游戏，我们该怎么做呢？其中的算法、循环、条件、变量、函数是什么样的呢？

魔力8球（纸上版）

在这个游戏中，我们要从1～20中选出一个数字，就需要4个五面的骰子或5个四面的骰子。但是，似乎六面的骰子更容易找到，我们就使用4个六面的骰子，把答案增加至24个。

这个游戏至少需要两个人玩。一个人充当“8球”，另一个人提出问题。提问的玩家问一个只能有“是”或“否”两种答案的问题，而“8球”摇动4个骰子（或1个骰子摇动4次），将其结果相加，然后参照上面的表格，给出结果。

这个游戏需要从1～24中产生一个随机数，然后我们才能查看表格中的答案。此时，我们通过骰子的使用“引入”了生成随机数的函数，由骰子负责数字部分。骰子，辛苦啦！

你发现我们规则中的Bug了吗？如果使用六面的骰子，那么绝对不会得出小于4的数字。我们又该如何调整表格中的答案呢？

变量

在上一节描述函数时（见第106页）我们曾提到过变量。变量就像一个容器，里面装有名称和值。我们可以把任何想放入的数据放入其中，还可以依据使用变量的方式改变数据的值。

我们常常可以在电子游戏里见到变量，游戏角色的命长、剩下多少命都是变量。变量名保持不变（比如“命”），变量值却可以改变（比如游戏角色死了，玩家的命就会减少）。

人自身也有变量。出生时眼睛的颜色可能与现在不同，身高增加了，年龄也变大了：

这些变量你会一直拥有，值可能在一段时间之后保持不变，也可能因生理机能的变化而发生改变（你的年龄就一定会增长）。

简而言之，变量就是贴着标签放着物品的盒子（你可能会想到，变量的名称其实在盒子里面是不占据任何空间的）。

雪人游戏

雪人游戏是一种猜词游戏，非常适合于我们观察变量。雪人游戏是适合两个或两个以上的人来玩的游戏。

游戏规则

第一个人（玩家1）想到一个单词，并为这个单词的每个字母都画出一个空格作为占位符，比如我们以“binary”这个词为例。

第二个人（玩家2）来猜一猜组成这个单词的字母。每猜对一个字母，就把这个字母填写在占位符上。每猜错一个字母，就把这个字母写在占位符的下面，用线画去。如果玩家超过两个人，且玩家2猜错了，那么玩家3就可以接着猜了。游戏继续进行，猜词的玩家猜出了正确的单词，游戏就宣告结束，猜词玩家获胜。但是，如果猜词的玩家猜错了九次还没有猜出单词，玩家1获胜，游戏宣告结束。

玩家每猜错一次，玩家1就可以画出雪人一部分：

1.猜错第一次：画出底下那个最大的雪球。

2.猜错第二次：画出中间不大不小的雪球，即雪人的身子。

3.猜错第三次：画出上面最小的雪球，即雪人的头。

4.猜错第四、第五次：分别画出雪人的左右两只胳膊。

5.猜错第六次：画出雪人头上的帽子。

6.猜错第七、第八次：分别画出雪人的左右两只眼睛。

7.猜错第九次：画出雪人的胡萝卜鼻子。

那么，变量又在哪里呢？在雪人游戏中，我们可以找到的第一个变量就是这个神秘的单词（我们称为神秘单词）。游戏刚开始时，对于玩家2来说，神秘单词其实可能是字典上任何一个由6个字母组成的单词。此时，神秘单词对于玩家而言就是一个装着不确定值的盒子。而玩家1选择了神秘单词的值，神秘单词=‘brainy’。

在这个游戏中，可以确定的第二个变量就是玩家猜测的单词（我们称为所猜单词）。玩家1知道在游戏的过程中玩家2会一直猜测神秘单词，而他则会判断所猜单词是否等于神秘单词。

我们假设玩家2问道：“是‘brainy’这个单词吗？”

神秘单词=‘binary’

所猜单词=‘brainy’

（神秘单词==所猜单词）=假

恐怕不是，二号玩家，欢迎继续猜！

使用for循环控制游戏

还记得我们在第089页讲到过for循环是计数控制的循环吗？在雪人游戏中，玩家猜错的次数决定了游戏的结果。像这样以轮次为基础的游戏，我们就可以在循环中使用变量。

每位玩家猜错九次游戏就会结束。因而，我们可以创建一个叫“错误猜测”的变量，每次游戏开始时的值都为9，即错误数=9。

每次所猜单词不正确时，我们还需要从“错误数”这个变量上减掉一次。如下所示：

if所猜单词！=神秘单词，

then错误数=错误数-1。

还记得运算符吧，我们知道“！=”意思是“不等于”。当所猜单词与神秘单词不一样时，我们就从错误数中减掉1。请记住，我们可以在不改变变量的情况下增加、减去变量的值，就如同我们在电子游戏中增加、减去玩家的分数一样。

那么，当错误次数用尽时会怎么样呢？

if错误数==0

then结束。

游戏结束！

答案永远为3

还记得算法一节中那个猜年龄的游戏吗（见第085页）？这里还有一个相似的游戏，或许你以前玩过。在这个游戏中也用到了变量，你或许还没有意识到呢！

变量，依据不同的用途，会发生改变。在以下的例子中，有人告诉我们他的年龄，然后我们以此数字进行一些数学运算，但不论我们输入什么数字，结果总会是3。

1.让一个人随便想一个数字。

2.把这个数乘以2。

3.再加上6。

4.再除以2。

5.再减去开始想到的数字。

6.结果为3。

在步骤1中，你可以让这个人用他的年龄作为开始的数字，这样变量就成为人的年龄了。我们希望编写出的程序适合于任何年龄，所以我们最不愿意看到的结果是，程序只适用于某些特定年龄的人。我们可以将变量命名为人的年龄，进行如下编写：

（（（（人的年龄×2）+6）/2）-人的年龄）==3

茶壶游戏

在这个维多利亚时期的室内游戏当中，一位游戏发起者想出了一组同音异形异义词（一组发音相同但字形和意义不同的词语），然后造一个句子，同时用到这组词语的两个词义，但游戏发起者不能说出真正的词语，而要用“茶壶”来代替。

例子：我听说有一个小偷企图从建筑工地上茶壶茶壶大梁。（答案：steal（偷盗）/steel（钢铁））

猜词者与游戏发起者进行对话，从而猜出那组神秘的词语。游戏者要一直使用“茶壶”这个变量来回答问题，具体如下：

猜词者：“嗯，你今天都做什么了？”

游戏发起者：“我不得不茶壶寒冷的天气。”

对话继续，直到有人猜出那组词语赢得一分。如果没有人猜出来，那么游戏发起者赢得一分，再出一题。

在这一例子中，“茶壶”这个变量存在两个值。怎么能做到这一点呢？我们实际上使用了数组。数组就是拥有一系列值的变量——它将一系列同类型的数据集合在同一个名称下。

在上面最后一轮游戏中，变量“茶壶”只能指steal和steel中的一个，这里是steel（此处应是“应对、抵抗”的意思。——编者注）。也就是说，“茶壶”每次说出来就可以替代两个值中的某一个，即茶壶=[steal, steel]。

我要打包行李

另一个用到数组的趣味游戏叫作“我要打包行李”，通常是开车时大家一起玩的游戏。玩游戏时，第一位参与者先说：“我要打包行李，我要把……狐猴放进去。”下一位参与者接着说：“我要打包行李，我要把……狐猴和速写本放进去。”以此类推，不断地说下去。

游戏继续进行，直至有人搞混了前面所说的顺序，或者忘记了所说的东西接不下去了，游戏宣告结束。最后一个顺利“打包行李”的人就是赢家。

在此例中，我们创建了一个变量数组（就称为装箱单吧），并持续为其增加内容，直到有人脑袋中可存储变量数组的“内存用尽”（希望这个人脑袋不会崩溃）！

魔力8球

如果我们返回来再看前面的魔力8球（见第113页），我们也可以把答案表格中的答案列成一个从1～20的数组（或0～19，具体见下文）。

数组笔记

在代码和计算机研究中，一般从数字0开始计数，而不是从1开始。使用纸和骰子来玩魔力8球时，必须从1开始计数，这是因为其中引入了“随机数”函数的骰子上并没有0这个数字。但是，如果要将其编成计算机程序，并把答案编为一个数组，那么我们就会让计算机生成0～23的随机数，而不再是1～24了。

问题：为什么程序员不干活儿了呢？

回答：因为他没有数组。

调试

在学习编程思维与编码的过程中，我们会学到极其重要的一课：任何事情不总是一蹴而就的。计算机无法像人类一样思考，只能执行接受的指令，因而调试代码确保指令正确可行是编程重要的步骤。你会发现，在编写程序的过程中，一开始确定编程方案所用的时间可能并不多，大量的时间都会花在代码的调试上。奶酪三明治算法就是经过了三次修改才最终完成的。不过，程序每修改一遍，我们都会有新的收获。

到底什么是调试呢？

调试这一术语首先在其他行业中应用，而后才在计算机领域中广为流传。这一术语的出现要归功于美国海军少将格蕾丝·赫柏。20世纪40年代，赫柏在哈佛大学为计算机Mark II编写程序时，发现了一只真正的虫子（bug）——一只飞蛾钻进了计算机继电器，导致机器无法正常工作。据报道她曾说过“debugging the system（除去系统中的虫子）”这样的话语，调试（debugging，即除去虫子）这一术语于是就出现了。

调试与我们之前探讨过的许多术语一样，并非计算机或计算机科学专用的术语。19世纪末，爱因斯坦曾用“bug”一词形容“小错误、小困难”。也有人用“glitch（小故障）”“gremlin（小鬼）”这样的词语描述类似的情况，即目前某些无法确定的东西进入并损害了系统。

调试就是指仔细地检查编程过程、算法、流程图，排除并修复致使程序无法正常运行的问题或错误。

Bug的类型

我们可以将bug（程序错误）分为两种类型——语法类和逻辑类。语法类bug是指我们在表达、书写方式方面的错误。逻辑类bug则是指指令执行方式方面的错误以及算法未能按设计进行的问题。

试试看，能否从下面的算法中找出语法bug？

撸猫的方法（How to Pet a Cat）

1.提起猫咪（Pick up cat.）

2.把猫咪放在大腿上（Put cat on your lap.）

3.撸ca（Pet ca.）

4.把猫咪放下（Put cat down.）

在步骤3中，我漏掉了一个字母。假如计算机或机器人在运行这个程序的话，就会到处寻找“ca”，最终找不到就会崩溃。

撸猫的方法（How to Pet a Cat）

1.提起猫咪（Pick up cat.）

2.撸猫（Pet cat.）

3.把猫咪放在大腿上（Put cat on your lap.）

4.把猫咪放下（Put cat down.）

这次尽管我们可以撸猫了，但却没有让猫咪舒缓下来。因此，把猫咪提起——撸猫——再把猫咪放在大腿上，这样的算法就存在逻辑顺序问题。

那么，既有语法bug又有逻辑bug的程序又会是什么样呢？

撸猫的方法（How to Pet a Cat）

1.提起猫咪（Pick up cat.）

2.把猫咪放在嘴唇上（Put cat on your lip.）

3.撸ca（Pet ca.）

4.把猫咪放下（Put cat down.）

在这里，我一不小心将“大腿（lap）”打成了“嘴唇（lip）”。尽管这样的指令能够理解并执行，但是必然会导致出人意料的结果！

寻找bug时，需要我们返回去对代码逐行进行检查，这样又费时，又劳神。不过幸运的是，大多数编程语言的IDE都能在问题发生之前帮你把它找出来（大多数情况下，程序要是通不过IDE的检查是不能运行的）。

假如你没有使用IDE检查代码，那么检修错误的第一步，就是寻找算法中出错的部分。比如你编写了一个关于汽车游戏的程序，结果用来控制汽车的箭头按键出现了故障。那么，从什么地方开始查找问题较好呢？假如找不到故障部分呢？啊哈！这就要靠我们在代码中做出的详细注释了。

给代码加注释

在本书中，我们并没有接触真正的代码，也不会开门见山地介绍添加注释的具体方法。当然，不同的编程语言添加注释的方法各不相同。这里，我们就采用前面小节中的一些伪代码，来介绍如何添加注释。

注释是和代码写在一起的，但是又与代码不同，不会被计算机识别为需要运行的指令。这是因为每行注释码的前面都有一个特殊的字符，它会告诉计算机自动忽略其后的内容。

#下一行会把Hello world输出到屏幕上

print（“Hello world”）

在以上用Python语言输出“Hello world”的例子中，我们在代码的上面又添加了一行以#开头的内容（#可以称其为井号、井号标签，其实这个字符就是#号！）。在Python语言中，#表示忽略这行中的其他内容。你想加多少行注释都行，如下所示：

#Hello World v1

#A.Coder（程序员）

#

#This is my first Python program.（这是我的第一个Python语言程序。）

#

#The line below will output Hello world to the screen（下一行会把Hello world输出到屏幕上）

print（“Hello world”）

#That’s all-bye now！（到此为止，再见！）

尽管这个程序长八行，但是代码只有一行！要学会利用注释。你可能会花几天甚至几周的时间编写一个程序，如果在其中把自己所做的工作做成注释、记录，日后你会受益匪浅。所以你要记住啦，一定要做注释。

#23-Nov-2016 2203hrs（编程时间）

#A.Coder（程序员）

#Added new code to evaluate playerGuess variable against（添加新的代码，来判断变量-所猜单词，是否等于变量-神秘单词）

#mysteryWord variable（单词）

（神秘单词==所猜单词）=假

在代码、算法甚至是写在纸上大致的算法设计中都做好注释，这会在最后排除错误的环节中为你节省不少时间。不仅如此，若与人合作完成编程项目，也会对他人有所帮助。

小黄鸭调试法

有一种调试方法看似笨拙却出奇地有效，那就是“小黄鸭调试法”，也叫“小黄鸭法”。要使用这个方法，就要先买一个小黄鸭（就像放在浴缸里的那种），把它放在电脑旁的桌子上。然后，你可以给这只对编程一无所知的小黄鸭详细地解释程序中所有的细节。

这其中的道理就是，程序员在向不懂编程的外行人解释代码该如何运行时，常常能意识到程序中的错误。在这个过程中，程序员必须非常详细地解说代码运行的细节。忽然，程序员“啊”了一声，意识到了错误所在，自己就解决了问题。可爱的小黄鸭就坐在那里，表情愉悦，乐于服务，而且会保守秘密。

在日常生活中，我们也经常能见到函数、变量、循环、算法，同样我们也一直在积极地进行着“调试”。无论何时，只要学习新的技能，就一定会犯错误。不过，只要我们勤于练习、持之以恒，就会不断地进步。

第四章　继续努力

还该做什么？

若想用较少的代码材料创造更多的代码与程序，注意下面几点，会很有帮助。

熟练使用工具

人们常说，可以使用的最佳工具往往就摆在面前。纸和笔、智能手机或者计算机，这些都可以成为我们最好的工具。

无论使用哪种工具，我们一定要对这种工具非常地熟悉和了解。另外，我们还要有乐于助人的精神，愿意帮助他人用好这些工具。要彻底地熟练掌握IDE软件（见第070页）。

熟练使用快捷键

使用计算机，不仅仅是为了编写代码，还要考虑如何提高效率。

计算机的每个程序和操作系统都有一系列的快捷键，旨在减少手指在鼠标和触控板之间来回移动，以便提高工作效率。

要求和细节设计

如果想设计一款游戏或者其他程序，在动手之前，最好先写出基本的要求。详尽的细节可以之后慢慢去完成，因为我们往往会觉得程序不够完美，会没完没了地做下去。所以，给自己定个截止日期，这样就会习惯按时完成。

你也许会不由自主地想把所有的奇思妙想都放进一项设计中去。但是，你要知道，一旦你真这么做了，这个设计也许永远都无法完成。

设定时间与细节要求，可以确保项目按时完成。你的各种奇思妙想可以用于以后其他的设计。（想一想“愤怒的小鸟”游戏有多少款啊！）

写日志

日志是记录进度的好办法，一支铅笔、一张纸，随时记下在编写的代码、要解决的问题以及其他相关的东西。而且用笔和纸做记录，还可以让你暂时离开计算机的屏幕，短暂地休息一会儿。

如果你对编程充满了热情，你的日志很快就会成为你履历中不可缺少的一部分。你也许都想象不到你以后的程序设计会多么成功！

适时地远离电子设备

缩着头，躬着背，伏在电脑桌前，大口吃着垃圾食品——那种昔日程序员的典型形象早已过时了。要记住：你是未来的程序员，要时刻保持头脑清醒、充满活力。饮食要讲究营养，要重视锻炼身体，还要定期离开电脑等电子设备，确保晚上得到足够的睡眠。

时刻为用户着想

要考虑那些使用你编写的程序的人，他们会怎样理解和使用你所开发的程序。作为程序员的你，对自己编写的程序了如指掌，但是这并不意味着，你的目标用户也对其知之甚详。所以，你必须站在使用者的角度思考问题。

你可以有计划地找人测试程序，以便获得有效的反馈。最终的用户和测试参与者可能会点击某些你没有让他们点击的东西，也许这反而能暴露出程序设计中的某些不足之处。所以请记住，有了他们的存在，你会得到很多帮助。

编码，要注重合作

不要一个人闭门造车，要注重合作。找个志同道合的人，让他们帮助你测试你编写的程序，他们提供的意见，可以帮你完善你的程序设计。加入一些在线的程序社区或者当地的创客空间，看看你能不能参与他们的一些活动。

接纳错误，从中学习

要知道事情不会都是一帆风顺的。要学会接纳错误，并从中学习，提升自己。学会从别人建设性的批评中汲取营养（但同时也要学会捍卫自己的观点）。

代码的注释很重要

在代码中加上注释。也许你认为这是画蛇添足。但是，将来当你再看这项程序或者与人合作的话，注释的作用就显得尤为突出。

一目了然的注释能提高程序员的工作效率，在程序设计中，会事半功倍。注释时，要注意表述清楚。要知道用户可能一开始并不了解代码的相关知识，他们需要一本指南书。

同时，要注意，如果对代码做出调整，不要忘了，也要相应地修改注释。

不断学习

作为程序员，需要孜孜不倦，终身学习，才能跟上日新月异的科技发展步伐。每一个人，不管年龄大小，都能发挥重要的作用，多下功夫，至少学习两种编程语言。在程序设计方面，总有新的知识，等着我们去学习。因此，要时刻保持热情，不断学习并积极帮助喜欢编程的人学会编程思维。

学习他人的语言表达方式

在学习编码时，还要经常与不熟悉代码的人打交道。这中间有你的上司、客户、同事，还有你的亲人。了解他们观察世界的视角，也能帮助自己提高交际能力，我们不仅要擅长和计算机打交道，也要善于与人沟通。

助人为乐

帮助他人提高，主动协助他人编码。要研究其他代码，要多提问题！有很多对编码有兴趣的人，他们等着你加入其中。

花时间做计划

编程不要超出规划，花点时间事先做好安排。如果在编码过程中，萌发了一些惊艳、神奇的想法，就花点时间记下来，可供以后使用。

做好备份

一定要记得做好备份，建立一个备份系统。其实现在已经很难见到哪台计算机里面没有备份系统的啦。要学会版本控制，把你修改的程序存放到程序库中。

寓编程于娱乐

虽然学习编程是为了工作的需要，要以工作为导向，整天想着各种繁杂的数据。但也不要忘了，学会了编程，也提供了一种自我展示的方式。所以，也可以寓乐于其中，抽个时间为家人或者为社区做个游戏或者艺术呈现什么的。

让世界变得更加美好

挖掘潜在价值

20世纪40年代，有人研发了世界上第一台电子计算机——埃尼亚克，旨在拯救生命。而现今，人们使用计算机多是出于娱乐目的。虽然与过去相比，计算机现在更多地用于娱乐和查找信息，但是我们比以往更有机会去挖掘其运算能力，使其像程序员一样思考，继续为人们服务。

近些年，大学、公司和程序员俱乐部，都在开展各种社会活动。人们借用专业技能和编程思维，努力使世界变得更加美好。不管是帮助向发展中国家捐赠物品的慈善机构创建网站，还是为南美医疗培训公司发布志愿者征集信息，这些行为都会使世界发生改变。

肩负着伟大的历史使命

编程思维，这是你的超级能力，你可以选择如何使用这种能力，而且不需要进行全球性的倡议。因为有了程序，这一切都如此容易，就像是在当地的编程俱乐部做一项志愿活动，或者说就像教授三倍于你年龄的人学习编程一样。问问周围的人，看看你是不是可以在他们学习编程的过程上提供帮助。

又到了做游戏的时间了吗？

单码密码轮

如果计算机可以采用二进制来表示0和1以外的其他数字，那么计算机又是怎样来识别数字以外的其他东西呢？其实，任何数字、符号或字母，都称为字符，计算机都能识别。二进制也并非计算机仅有的编码系统。例如，下一页就是一个例子，英语字母可以用统一码这个系统来表示。

这些只是小写英文字母的表示方式。大写字母，标点符号，以及其他符号还需要用不同的数字进行标记。值得庆幸的是，计算机的编码发展得很快，我们并不需要掌握所有的统一码字符。现如今在编码过程中，我们可以直接使用文字。

恺撒加密法

2000多年以前，尤利乌斯·恺撒就开始使用密码（当一个字母被另一个字母或符号代替就有了加密的效果），他采用将字母表中的字母移动三个位置的方式，对重要的军事信息进行加密。最常见的方法就是用密码轮将明文转化成密文。密码轮是由两个镶嵌在一起的轮子组成。外面的轮子代表着字母表中的26个字母。里面的轮子也同样代表着字母表上的字母，而且可以在外面的轮子里边旋转。

创建自己的密码轮

按照下面的指令创建一个密码轮，和朋友一起用这些神秘的代码进行交流。

把书中本页的密码轮复印下来（切记不要剪下来）。

因为需要一个外轮和一个内轮，所以要复印两张。把两个轮子剪下来，然后重叠放在一起，在中心部分订在一起，确保两个轮子都能转动就可以啦。你也可以在一个轮子上使用统一码。

生活，就是编程思维

现在你已经知道编程思维了，那么编程思维到底意味着什么呢？学习思维模式，就意味着有能力创造性地解决问题、表达思想。

其实，你早已经在创造性地解决问题、表达思想啦。但问题在于，你可能还不知道如何以编程思维的视角去看待生活中的方方面面。

·如果你喜欢作曲，你就知道如何运用编程思维。

·如果你想设计舞步，你就会知道如何运用编程思维。

·如果你喜欢打篮球，那么你也会知道如何运用编程思维。

编程思维，计算机思维，电脑科学，不管你听到的是哪个术语，这些术语并不只是指数字、符号或者代码，最重要的是指如何创造性地解决问题。

正如之前所说，我们甚至不需要使用计算机就可以创造性地解决问题。计算机只是你可以使用的一种工具（除了你身旁的小黄鸭）。

编程思维，虽然包括理性推理、逻辑思维和数学运算，但实际上，它就是做事——做大事的媒介。计算机并不是无所不能的，它完全在人的控制之下，要了解计算机的工作原理，你必须自己去学习。在这个世界上，更有智慧、真正强大的，其实不是计算机，而是具有创造性解决问题能力的我们人类。

拯救西北太平洋树章鱼

在上文中我们提到过批判性思维，现在我们有必要对其进行审视，以便搞清楚它到底是什么。世间的所有人都相互关联。截至2014年已经有超过10亿的网页，而到2019年智能手机用户有望达到25亿，所以在很短的时间内，我们可以获得希望获得的任何信息。

但是，这并不意味着我们获得的所有信息百分百准确。不妨请进入西北太平洋树章鱼网页。

稍作研究，你就会发现西北太平洋树章鱼——这种生活在北美西海岸奥林匹克岛上的热带雨林的野生动物正濒临灭绝。有个网站详细地介绍了树章鱼的生存境况。环境的污染，天敌的威胁，使这个物种濒临灭绝。你可以在邮件列表上签名，在推特上标注支持，甚至可以通过买个咖啡杯，来为保护树章鱼做点贡献。

然而，事实却让人大跌眼镜，树章鱼根本不存在，这个网站是个互联网恶作剧（从1998年就开始啦）。现在，该网站主要用于检测学生的互联网素养。甚至直到今天，该网站还能继续误导学生，使他们误以为树章鱼真实存在且由于野人的捕食而濒临灭绝。

我们可以轻点鼠标搜索到来自世界各地的相关信息，却很难辨别信息的真伪。对于程序员来说，互联网是最常用的基本工具。在编程过程中，遇到一些问题，各大网站上也常常能找到解决的办法。不过，你首先要彻底把问题搞清楚了，然后再在网上搜索解决的办法。花点时间去研究程序设计语言文本，选择合适的编程语言，或者与了解编程的同伴、指导者进行一对一的交流，寻求专业性的帮助。所获得的解决方案，也要进行认真分析并对出处进行评估，以确保其真实可靠。

再谈计算机思维

计算机思维可以分解为四个部分：

·问题分解

·模式识别

·抽象思维

·算法设计

这些词都很重要，为了便于更好的理解，我们用更为简单的术语来解释。

问题分解

想一想一部电影是如何制作并剪辑完成的。好莱坞的电影制作团队，从视觉效果团队、服装师到餐饮服务人员，一般都有好几千人。虽然在屏幕上仅仅只看见有限的几个演员以及导演和制片人的名字，其实他们的背后是一个庞大的团队。这些人共同协作，才能保证电影制作完成并顺利发行。

如果我们把好莱坞电影看作一个需要解决的大问题，那么演员和相关摄制工作人员就是问题的组成部分，所有这些组成部分共同协作才能最终解决这个大问题。

模式识别

进行模式识别，可以帮助我们发现和解决与模式相关的问题，因此模式识别作为编程思维的第二步，有助于我们进一步分解问题。举个例子来说，你如果想在某个网站上提交信息，你必须先在某一点上进行模式识别，也就是常说的CAPTCHA（验证码）验证，这种验证方法受到许多网络公司的青睐，用以防止计算机或者自动软件伪装成用户开启别的功能。强迫计算机使用者进行模式对接测试，是目前防止此类软件骚扰的有效办法。

在上图的验证码中，我们必须确认所有含有树形的图片，而这正是目前计算机所无法自动生成的。

你知道吗？

其实，只要做些拼图游戏一样简单的事情，就能获得很棒的模式识别技术。

抽象思维

举个例子，我要在星期六下午三点，到朋友亚当家去。我住的地方离他家有7.2英里。星期六早上，我要先给狐猴喂完食，再去游泳。然后，要在下午一点在城北的一家咖啡馆吃午饭，估计两点之前可以吃完。咖啡馆离朋友家还有3.1英里。那么，在两点到三点这一小时内，我得走多远的路呢？

使用抽象思维时，我们要剔除那些与手头问题无关的信息。例如，我住的地方离亚当家有多远，这就无关紧要，因为星期六下午，我吃饭的地方离他家更近。至于我要喂食狐猴、去游泳，也都与去亚当家无关。唯一相关的信息只有一个：

咖啡馆距亚当家有3.1英里。

现在我们回过头来再看看那些好莱坞大片，回顾下这样的场景：在外面观看影片的过程中，脑海中出现了一些令人惊骇的场面，然而屏幕上并未出现那般恐怖的景象。导演有时会花费数百万美元，有意利用镜头，拍摄演员面对屏幕上的怪物而做出惊骇的表情，目的在于制作特效，创造紧张氛围。

算法设计

完成以上步骤后，就是编程思维的最后一步了，将从问题分解、模式识别和抽象思维中提取的问题进行设计、检测。为了更清晰地解释这个步骤，我们去见一见约翰·卡尔·弗里德里希·高斯。

会见高斯

如果叫你把1～100的所有数字用心算的方法加起来，你能做到吗？如果可以做到的话，你需要花多长时间呢？

早在公元1785年，高斯的老师就给学生们出了这道题。正如故事所叙述的那样，高斯的老师给学生出这道题，本希望能多占用一些课堂时间。但是出乎老师的意料，高斯很快给出了答案：5050。

你知道吗？

不要因为没有看出高斯所发现的规律而伤心！高斯可是个数学天才，他一生有很多重大发现。他死后，他的大脑都没有随着身躯一起下葬——他的大脑被送到哥廷根大学去做研究。时至今日他的大脑还在哥廷根大学呢！

高斯并不是死板的将这些数字一个个相加（1+2+3+……+98+99+100）。他发现这些数之间有一个规律，就是将这组数首尾相加都会出现相同的结果：1+100=101，2+99=101，3+98=101……一共有50组这样的数字相加。因为1～100中间的数是50，所以高斯只需要计算50×101，最后的答案就是5050。

高斯不是计算机方面的专家，在他的时代也没有计算机，他只是个8岁的孩子。但是高斯很聪明，善于创造性地解决问题。他将复杂问题简单化（把大问题简化分解成易于处理的小问题），找出其中的规律性，例如这道题中，每对首尾数字相加，得数相同；采用抽象思维，略去不必要的解题步骤，在这道题目中，并不需要将数字依次相加，而是应该把它转为乘法进行运算。

著名的科幻小说作者和未来学家亚瑟·克拉克曾经说过：“科学技术的最高境界无异于魔术。”

然而魔术的问题在于，当魔力消失以后，没有人能够使其复原。但是，如果我们学习编程思维，我们就可以把握科技发展的脉搏。

词汇表

算法（Algorithm）：为解决问题而规划的一系列步骤和规则（见第083页）。

人工智能（artificial intelligence）：指计算机拥有像人类一样的智能。

二进制（binary）：一种只有开和关两种状态的数字和计算系统。

布尔型（Boolean）：一种只包括真和假两种值的数据类型。

代码（code）：指字符和符号，能够用来表示其他字符、符号。

注释（comments）：指在代码中添加的注释，方便程序员日后查阅（见第133页）。

条件（condition）：用于判断真假。

约束条件（constraints）：一些影响问题或项目范围的限制性因素。

核心（core）：CPU中接受指令并按照指令执行动作、计算的部分。

跨平台（cross-platform）：指软件、应用程序能够在不同的系统（或平台）呈现相同的表现。比如，愤怒的小鸟这款热门游戏，就可以在比如iOS系统，Android系统，Windows Phone系统，Windows系统，MacOS系统，Playstation游戏机，Xbox游戏机等多个计算机平台、游戏平台上运行。

数据（data）：一般指储存在计算机中的程序、文稿、数字、图像等信息。

数据语言（data language）：用于处理数据的语言，比如用于数据统计的R语言、用于数据库查询和程序设计的结构化查询语言（SQL）。

调试（debugging）：指代码运行有误时，程序员找出其中错误并进行修复的过程（见第129页）。

十进制（denary）：指人们惯常使用的数字（1～10）系统，也称为十进位制。

高效（effective）：是指以最小的努力收获最大的效益。

编码/解码（encoding/decoding）：把数据转化成计算机语言或把计算机语言转化成数据的过程。

判断（evaluate）：指把值与值进行比较，然后得出相应的结论。

可执行（executable）：指计算机文件、程序是可以运行的。计算机程序有时亦称为“可执行文件”。

执行（execute）：指计算机接受并完成程序指令的过程。

文件（file）：计算机用以存储数据、信息的文档。

流程图（flow diagram）：一种直观的过程呈现方式，包括开始、结束和具体的步骤（见第061～062页）。

集成开发环境（Integrated Development Environment, IDE）：能够帮助编程者编写代码的软件工具。

缩进/行首缩进（indented/indentation）：指使用空格来编排代码的格式。有些编程语言要求在每个语句前打出一定数量的空格，从而保证代码易于读取和执行。

输入/输出（input/output）：输入是指让信息进入计算机；输出是指计算机将其内容显示、打印或拷贝出来。

物联网（Internet of Things）：指与互联网相连接的设备或称“智能”设备，如智能电灯、智能烤箱、智能恒温器等，在互联网的作用下能够协同运作。物联网这股潮流呈现持续火热的发展态势。

逻辑（logic）：用来帮助程序员找到编程解决方案的推理原则。

逻辑错误（logic bugs）：指令执行过程中出现的错误。

循环（loop）：一种程序中重复的步骤却无须重复编码的有效编程方法（见第087页）。循环分为两种：for循环和while循环。

机器码（machine code）：计算机上的微处理器能够识别的原生代码。

元数据（metadata）：与数据有关的信息。

微处理器（microprocessor）：大体上相当于计算机的大脑。

面向对象的程序设计（Object-Oriented Programming, OOP）：见第074页。

运算符（operators）：表示算术运算和比较运算的符号。

补丁（patch）：对错误代码进行的修复。

外部设备（peripherals）：指接入计算机的设备，能拓展计算机的功能，可方便使用者操作，比如键盘。

像素（pixels）：计算机屏幕上图像最小的单元。

编程语言（programming languages）：指作为程序员和计算机沟通桥梁的软件。

伪代码（pseudocode）：用来描述如if、then、else这样一组指令的语言。

穿孔卡（punch cards）：早期的一种计算机编程系统，计算机使用打有孔的纸片代表数字信息。

随机存储器（Random Access Memory, RAM）：计算机的内存储器。

卡片式电脑（Raspberry Pi）：一种微型计算机，使用者可将其与电视机或其他显示器相连，再接入键盘，就能用来学习编程。

小黄鸭法（rubber ducking）：指使用小黄鸭作为公平公正的听众来倾听编程者讲述编程内容（见第135页）。

脚本语言（scripting languages）：指程序运行前不需要进行编译的编程语言，比如AppleScript（苹果公司开发的脚本语言），JavaScript的转译语言（CoffeeScript），VB Script（微软公司开发的脚本语言）。

服务器（server）：指为特殊目的服务的计算机，比如游戏“我的世界”（Minecraft）的服务器，就是只用来设计和配置运行多人游戏的计算机。

推出（ship）：指项目的完成、发出、转交、发布。

语句（statements）：独立的代码行。

单步调试（step through）：指一步一步检查代码的过程。

流媒体技术（stream）：指计算机在有效下载文件的同时可执行文件的能力，能够节省存储空间。常见于如声田（Spotify）、网飞（Netflix）等娱乐程序中。

成功标准（success criteria）：设定一个既定目标以便评估努力是否有效。

三段论（syllogism）：逻辑推理的一种形式，因刘易斯·卡罗尔而广为流传（见第048页）。

语法（syntax）：规定编程语言表达、书写和理解的规则。

语法错误（syntax bugs）：指指令识别方面出现的错误。

语法高亮（syntax highlighting）：某些集成开发环境（IDE）软件能够直观地显示出语法正确的部分、提示语法使用方式的功能。

晶体管（transistor）：微型电子设备，能增强电流，也能控制电流的开关。

图灵测试（Turing test）：1950年由阿兰·图灵设计而成，用于测试机器的人工智能，主要检验计算机的表现能否与人类的表现无异。

普适计算（ubiquitous computing）：描述计算机及其系统广泛应用、无处不在的概念。

万国码、统一码（Unicode）：描述字符的一套标准，以方便计算机对字符进行识别。

变量（variable）：占位符或“箱子”，能容纳各种数据类型及其值。

拓展阅读

在学习编程的旅程中，关于编程和计算机方面的知识将与你一路同行。当然，你可以使用以下这些资源来获取更多知识信息：

学习批判性思维和逻辑推理

阿里·阿莫萨维《神逻辑：不讲道理的人怎么总有理》（An Illustrated Book of Bad Arguments）

（免费阅读网址http：//almossawi.com/bookofbadarguments.html）

阿里·阿莫萨维《糟糕的选择》（Bad Choices）

关于马丁·加德纳（http：//martin-gardner.org/）

刘易斯·卡罗尔的作品（http：//www.lewiscarroll.org/carroll/texts/）

在计算机方面具有突出贡献的大人物

比尔·盖茨（微软公司联合创始人）（https：//en.wikipedia.org/wiki/Bill_Gates）

史蒂夫·乔布斯（苹果公司联合创始人）（https：//en.wikipedia.org/wiki/Steve_Jobs）

林纳斯·托瓦兹（Linux操作系统之父）（https：//en.wikipedia.org/wiki/Linus_Torvalds）

马库斯·泊松（游戏我的世界创始人）（https：//en.wikipedia.org/wiki/Markus_Persson）

在计算机方面具有突出贡献的组织机构

电子前线基金会（The Electronic Frontier Foundation）（https：//www.eff.org/）

Raspberry Pi基金会（The Raspberry Pi Foundation）（https：//www.raspberrypi.org/）

Arduino网站（https：//www.arduino.cc/en/Guide/Introduction）

开放源代码促进会（Open Source Initiative）（https：//opensource.org/）

在线学习

可汗学院（https：//www.khanacademy.org/）：免费获取资源，自我掌控进度，学习数学、科学、编程等。

斯维加特《Python编程快速上手让烦琐工作自动化》（http：//automatetheboringstuff.com/）

麻省理工学院开发的编程工具Scratch（https：//scratch.mit.edu/）

更多资源敬请访问：coder.jimchristian.net。

Table of Contents

扉页

版权信息

第一章 学会编程思维

学会编程思维

什么是编程？

计算机无处不在

计算机的特征

计算机如何工作？

计算机的出现

编程与计算机的历史

人人都能学会编程

世界需要更多的编程者

第二章 解决问题

解决问题

大脑是怎样工作的？

解决复杂的问题

脑力训练

更多逻辑谜题

约束条件

编程就是要简单

第三章 学习编程语言

学习编程语言

编程语言的语法规则

编程的形式

面向对象程序设计（OOP）

不同的数据类型

数据结构

算法

循环

条件语句

流畅的运算符

趣味函数

变量

调试

第四章 继续努力

还该做什么？

让世界变得更加美好

又到了做游戏的时间了吗？

生活，就是编程思维

再谈计算机思维

词汇表

拓展阅读