新書推薦:
《
生成式人工智能:AIGC与多模态技术应用实践指南
》
售價:HK$
108.9
《
石油帝国的兴衰:英国的工业化与去工业化
》
售價:HK$
97.9
《
古典的回響:溪客舊廬藏明清文人繪畫
》
售價:HK$
437.8
《
根源、制度和秩序:从老子到黄老学(王中江著作系列)
》
售價:HK$
121.0
《
索恩丛书·北宋政治与保守主义:司马光的从政与思想(1019~1086)
》
售價:HK$
75.9
《
掌故家的心事
》
售價:HK$
85.8
《
农为邦本——农业历史与传统中国
》
售價:HK$
74.8
《
郊庙之外:隋唐国家祭祀与宗教 增订版 (三联·哈佛燕京学术丛书)
》
售價:HK$
105.6
內容簡介:
本书是深受师生欢迎的优秀C++入门教材。作者结合自己多年的教学经验精心设计并编撰了本书内容。采用了很多便于巩固所学知识的设计,例如各章开头的小节总览,书中随处可见的小结框、编程提示和编程陷阱,各章结尾的小结、习题、编程练习和编程项目等。这些非常适合初学者掌握重要的编程概念。
全书共18章,8个附录。在讲解C++基础知识之后,直接引导学生深入函数、IO流、类、控制流程、命名空间、数组、字符串、指针和动态数组、递归、模板、指针和链表、派生类、异常以及标准模板库。
目錄 :
目 录
第1章 计算机和C++编程入门1
概述2
1.1 计算机系统2
硬件2
软件5
高级语言6
编译器7
1.2 编程和问题求解9
算法9
程序设计10
面向对象编程12
软件生命周期12
1.3 C++入门13
C++语言的起源13
一个C++示范程序14
简单C++程序的布局17
编译和运行C++程序19
1.4 测试和调试21
程序错误的分类22
小结24
自测题答案24
编程练习25
编程项目26
第2章 C++基础知识29
概述30
预备知识30
2.1 变量和赋值30
变量30
名称:标识符32
变量声明33
赋值语句34
2.2 输入和输出37
使用cout进行输出37
include预编译指令和命名空间38
转义序列39
格式化带小数点的数字41
用cin进行输入42
设计输入和输出43
2.3 数据类型和表达式44
int类型和double类型44
其他数值类型45
C++11类型46
char类型47
bool类型48
string类简介48
类型的兼容性49
算术操作符和表达式51
更多赋值语句54
2.4 简单控制流程54
一个简单的分支机制54
复合语句59
简单的循环机制61
递增操作符和递减操作符63
2.5 程序风格66
缩进67
注释67
为常量命名68
小结71
自测题答案71
编程练习74
编程项目76
第3章 更多的控制流程79
概述80
预备知识80
3.1 使用布尔表达式80
布尔表达式求值80
枚举类型选读85
3.2 多 路 分 支86
嵌套语句86
多路if-else语句88
switch语句92
为菜单使用switch语句95
语句块96
3.3 C++循环语句详解99
while语句回顾99
再论递增操作符和递减操作符100
for语句102
应该使用哪种循环106
break语句108
3.4 设计循环109
求和与求乘积的循环109
终止循环111
嵌套循环113
调试循环114
小结117
自测题答案117
编程练习121
编程项目122
第4章 过程抽象和返回值的函数125
概述126
预备知识126
4.1 自顶向下设计126
4.2 预定义函数126
使用预定义函数127
随机数生成130
强制类型转换131
强制类型转换的古老形式133
4.3 程序员自定义函数134
函数定义134
返回布尔值的函数138
另一种形式的函数声明138
函数定义语法小结140
再论函数定义的位置140
4.4 过程抽象142
黑盒的比喻142
4.5 作用域和局部变量151
函数如同小程序151
全局常量和全局变量153
传值形参是局部变量155
块作用域156
再论命名空间157
4.6 重载函数名称160
重载入门160
自动类型转换164
小结166
自测题答案166
编程练习169
编程项目170
第5章 所有子任务的函数173
概述174
预备知识174
5.1 void函数174
void函数的定义174
void函数中的return语句177
5.2 传引用参数178
初探传引用调用179
传引用调用详解180
混合的参数列表185
5.3 使用过程抽象188
在函数中调用其他函数188
前条件和后条件189
5.4 测试和调试函数194
存根和驱动程序194
5.5 常规调试技术197
兼容并蓄,不抱偏见198
检查常见错误198
定位错误198
assert宏200
小结202
自测题答案202
编程练习205
编程项目206
第6章 IO流:对象和类入门209
概述210
预备知识210
6.1 流和基本文件IO210
文件之于IO的重要性211
文件IO211
类与对象入门214
文件IO技术218
追加到文件选读220
文件名作为输入选读221
6.2 流IO工具224
用流函数格式化输出224
操纵元227
流作为函数实参228
命名空间的问题231
6.3 字符IO233
成员函数get和put233
putback成员函数选读236
函数的默认实参选读240
eof成员函数243
预定义字符函数246
小结249
自测题答案249
编程练习254
编程项目254
第7章 数组259
概述260
预备知识260
7.1 数组入门260
声明和引用数组260
数组在内存中的表示263
初始化数组265
7.2 函数中的数组267
索引变量作为函数参数267
整个数组作为函数参数269
const参数修饰符271
返回数组的函数273
7.3 数组编程282
部分填充数组282
7.4 多维数组292
多维数组基础292
多维数组参数293
小结298
自测题答案298
编程练习301
编程项目302
第8章 字符串和向量309
概述310
预备知识310
8.1 字符串的数组类型310
C字符串值和C字符串变量311
cstring中的其他函数315
C字符串输入和输出318
C字符串到数值的转换和可靠输入320
8.2 标准string类324
标准类string简介324
string类的IO326
用string类进行字符串处理330
string对象和C字符串之间的
转换335
字符串和数字之间的转换336
8.3 向量336
向量基础知识336
效率问题339
小结341
自测题答案341
编程练习343
编程项目343
第9章 指针和动态数组349
概述350
预备知识350
9.1 指针350
指针变量351
基本内存管理356
静态变量和自动变量356
9.2 动态数组359
数组变量和指针变量359
创建和使用动态数组361
指针运算选读364
多维动态数组选读365
小结367
自测题答案367
编程练习368
编程项目368
第10章 定义类373
概述374
预备知识374
10.1 结构374
用于异种数据的结构374
结构作为函数参数378
对结构进行初始化380
10.2 类382
定义类和成员函数382
公共成员和私有成员386
总结类的一些特征396
用于初始化的构造函数397
10.3 抽象数据类型405
用于生成抽象数据类型的类405
10.4 继承411
派生类412
定义派生类413
小结416
自测题答案416
编程练习420
编程项目420
第11章 类中的友元函数、重载
操作符和数组425
概述426
预备知识426
11.1 友元函数426
友元函数428
实现digit_to_int选读435
const参数修饰符437
11.2 重载操作符441
重载操作符442
用于自动类型转换的构造函数444
重载一元操作符445
重载和446
11.3 数组和类452
类数组452
数组作为类成员455
11.4 类和动态数组458
析构函数460
拷贝构造函数463
重载赋值操作符467
小结470
自测题答案470
编程练习476
编程项目477
第12章 独立编译和命名空间483
概述484
预备知识484
12.1 独立编译484
ADT回顾484
使用#ifndef492
12.2 命名空间495
命名空间和using预编译指令495
创建命名空间496
限定名称498
命名空间的微妙之处选读499
无名命名空间500
小结505
自测题答案505
编程练习506
编程项目508
第13章 指针和链表509
概述510
预备知识510
13.1 节点和链表510
节点511
nullptr513
链表514
在表头插入节点515
搜索链表518
指针作为迭代器520
在列表中插入和删除节点521
链表的变体524
类构成的链表526
13.2 栈和队列528
栈528
队列532
小结536
自测题答案536
编程练习538
编程项目538
第14章 递归545
概述546
预备知识546
14.1 面向任务的递归函数546
深入递归552
用于递归的栈554
递归与迭代555
14.2 面向值的递归函数556
要返回值的递归函数的常规形式556
14.3 递归思想560
递归设计技术560
小结570
自测题答案570
编程练习573
编程项目573
第15章 继承577
概述578
预备知识578
15.1 继承基础578
派生类580
派生类中的构造函数585
protected限定符588
重定义成员函数590
重定义与重载的比较592
访问重定义的基函数593
15.2 继承细节594
不继承的函数594
派生类中的赋值操作符和拷贝
构造函数595
派生类中的析构函数595
15.3 多态性596
晚期绑定597
C++虚函数597
虚函数和扩展类型兼容性601
小结607
自测题答案607
编程练习610
编程项目612
第16章 异常处理617
概述618
预备知识618
16.1 异常处理基础618
异常处理的简单例子619
定义自己的异常类625
多个throw块和catch块626
在函数中抛出异常629
异常规范630
16.2 用于异常处理的编程技术632
抛出异常的时机632
异常类层次结构634
测试可用内存634
重新抛出异常635
小结636
自测题答案636
编程练习637
编程项目638
第17章 模板641
概述642
预备知识642
17.1 用于算法抽象的模板642
函数模板643
17.2 用于数据抽象的模板651
类模板的语法651
小结657
自测题答案657
编程练习659
编程项目659
第18章 标准模板库663
概述664
预备知识664
18.1 迭代器664
using声明665
迭代器基础665
迭代器的种类670
常量和可变迭代器673
逆向迭代器673
其他种类的迭代器675
18.2 容器675
顺序容器676
容器配接器stack和queue679
关联容器set和map682
效率问题687
18.3 泛型算法688
运行时间和大O表示法689
容器访问运行时间691
不修改容器的算法692
会修改容器的算法695
set算法696
排序算法697
小结698
自测题答案698
编程练习699
编程项目700
附录1 C++关键字705
附录2 操作符的优先级706
附录3 ASCII字符集707
附录4 部分库函数708
附录5 内联函数712
附录6 重载数组索引方括号713
附录7 this指针714
附录8 将操作符重载为成员操作符716
內容試閱 :
第1章 计算机和C++编程入门
概述
1.1 计算机系统
硬件
软件
高级语言
编译器
先驱人物 查尔斯巴贝奇与艾达奥古斯塔
1.2 编程和问题求解
算法
程序设计
面向对象编程
软件生命周期
1.3 C++入门
C++语言的起源
一个C++示范程序
简单C++程序的布局
编译和运行C++程序
1.4 测试和调试
程序错误的分类
小结
自测题答案
编程练习
编程项目
分析的整个发展和运作现在都可以由机器来完成……分析机将指引未来的科学发展。
——查尔斯巴贝奇 1791—1871
概述
本章讲解计算机的基本组成,以及设计和编写程序的基本技术,然后展示一个示例C++程序,描述它是如何工作的。
1.1 计算机系统
计算机要遵循的一系列指令统称为程序。计算机使用的各种程序称为该计算机的软件。组装一台计算机所需的物理设备称为硬件。正如后文所述,计算机硬件在概念上是非常简单的。然而,现在的计算机都配备大量软件以辅助我们完成各种编程任务。这些软件包括各种编辑器、翻译器以及管理器等。最终的工作环境就是一个复杂的、功能强大的系统。本书几乎完全围绕软件展开,但首先有必要对硬件有一个基本的了解。
硬件
计算机主要分为PC、工作站和大型主机。PC个人电脑是体积较小的计算机,设计目的为每次由一个人使用。大多数家用电脑都是PC,但PC也广泛应用于商业、工业和科学领域。工作站其实是一台体积更大、功能更强的PC。可把它视为一种“工业”PC。大型主机则是更大的计算机,通常要求一组支持人员,而且要供多个用户共享。PC、工作站和大型主机并不是泾渭分明的,但利用这些术语,通常能表达与一台计算机有关的常规信息。
网络由大量相互连接的计算机构成,以便这些计算机共享资源比如打印机和信息。一个网络可能包含大量工作站以及一台或多台大型主机,另外还有打印机之类的共享设备。
由于本书的目的是学习编程,所以无论使用PC、大型主机还是工作站,都是无关紧要的。稍后就知道,这三种计算机的基本结构是相同的。
大多数计算机系统的硬件都像图1.1那样配置。计算机由5个主要部件构成:输入设备、输出设备、处理器也称为CPU、主存储器以及辅助存储器。处理器、主存储器和辅助存储器通常安装到一个机箱内部。处理器和主存储器是计算机的核心,可将其视为一个集成单元。其他部件与主存储器相连,并遵照处理器的指示工作。图1.1中的箭头指明信息流动的方向。
输入设备是允许用户将信息发送给计算机的设备。主要的输入设备是键盘和鼠标。
输出设备是允许计算机将信息发送给用户的设备。最常用的输出设备是显示器,或者称为监视器。计算机系统一般有多个输出设备。例如,除了显示器之外,计算机还可能连接了一台打印机,能在纸张上输出。有时将键盘和显示器统称为终端。
图1.1 计算机的主要组成部件
为了存储输入并像平时那样用草稿纸来演算,计算机提供了存储器。计算机要执行的程序也存储在存储器中。计算机支持两种形式的存储器,分别为主存储器和辅助存储器。要执行的程序存储在主存储器中。正如主存储器这个名称所暗示的,它是最重要的存储器。主存储器相当于一个很长的编号位置列表,这些位置称为存储位置或者内存位置。在不同计算机中,内存位置的数量也是不同的,从几千到几百万都有,有的甚至能达到几十亿。每个内存位置都包含一系列0和1。这些位置的内容可以改变。所以,每个内存位置都可被视为一块小黑板,计算机可在上面擦写。在大多数计算机中,每个内存位置的0或1个数相同。只能包含0或1的数位称为一个二进制位,或者称为位或比特。大多数计算机的内存位置都包含8位或8位的倍数。每8位称为一个字节,所以可以将这些编号内存位置称为字节。换言之,可将计算机的主存储器视为一个很长的编号存储单元字节列表。对字节进行标识的编号称为该字节的地址。一个数据项数字或字母可存储到其中一个字节中。以后需要该数据项时,就根据那个字节的地址来查找数据项。
如果要处理的数据项太大比如一个很大的数,以至于一个字节容不下,就使用几个相邻的字节容纳它。在这种情况下,用于容纳该数据项的整个内存块仍然称为一个内存位置。构成这个内存位置的第一个字节的地址作为这个较大的内存位置的地址。所以,一种更准确的说法是:可将计算机的主存储器视为一个很长的内存位置列表,每个位置长度可变。每个位置的长度用字节数来表示,第一个字节的地址成为该位置的地址。图1.2展示了一台假想计算机的主存储器。每个内存位置的长度都不是固定的,在计算机上运行一个新程序时,它们可能发生改变。
图1.2 内存位置和字节
字节和地址
主内存被划分成称为字节的多个编号位置,一个字节的编号就是该字节的地址。一组连续的字节可作为一个数据项比如数字或字母的存储位置。组内第一个字节的位置就是这个更大的存储位置的地址。
在计算机存储器中,虽然信息实际表示成0和1,但用C++或其他大多数编程语言编程时,不必过于关心这个事实。不过,一旦开始写程序,许多人仍然希望知道0和1具体是如何使用和转换的。计算机必须将这些0,1序列解释成字母、数字、指令或者其他类型的信息。计算机根据特定的编码方案来自动执行这些解释。存储在计算机存储器中的每种类型的数据项都要采用一种不同的编码:字母使用一种代码,整数使用另一种代码,小数使用另一种代码,指令使用另一种代码,依此类推。例如,在一个常用的代码集中,01000001是字母A的编码,也是数字65的编码。为了确定特定位置中的01000001代表的是什么,计算机必须跟踪记录目前那个位置目前使用的是哪一种编码。幸好,程序员很少需要关心这些编码,并可放心地假定位置中包含了实际的字母、数字或者其他数据项。
为什么是8
每个字节都代表一个能容纳8个二进制位的内存位置。那么,8有何特别之处?有两个原因使8显得很特殊。首先,8是2的3次方。由于计算机在最底层使用的是二进制位,而每一位只有两个可能的值,所以2的乘方用起来比10的乘方更方便。其次,需要8位1个字节才能对一个字符比如一个英语字母或其他键盘符号进行编码。
到目前为止,我们讨论的都是主存储器。没有主存储器,计算机不能做任何事情。但是,只有计算机真正按照一个程序中的指令工作时,才会用到主存储器。计算机还有另一种形式的存储器,称为辅助存储器或辅助存储。辅助存储器能在计算机使用之后和之前持久性地保存数据。还可以将辅助存储器称为辅助存储设备、外部存储器或者外部存储。
在辅助存储设备中,信息以文件为单位来保存。文件可大可小。例如,程序平时存储在辅助存储设备上的文件中,并在程序运行时复制到主存储器。任何形式的信息都可存储到文件中,包括程序、信函以及存货单等。
计算机允许连接几种不同的辅助存储设备。最常见的有硬盘、软盘、CD、DVD和可移动闪存驱动器。计算机使用的CD和音乐CD基本相同,而DVD和视频DVD基本相同。计算机使用的CD和DVD可以是只读的,只能读取上面的数据,不可更改;也可以是可读可写的,计算机可以更改上面的数据。硬盘通常固定在计算机内,不能随便取出。相反,软盘和CD很容易从驱动器中取出,并拿到另一台计算机上使用。软盘和CD的优点在于便宜和易于携带,但硬盘能存储更多的数据,而且速度更快。如今,闪存驱动器已在很大程度上取代了软盘,使用名为闪存的存储介质来存储数据。和主存储器不同,闪存驱动器即使没有供电,上面存储的数据也不会丢失。虽然还有其他形式的辅助存储设备,但这些形式是最常见的。
主存储器除了简称为内存,还可简称为RAM,也就是随机存取存储器Random Access Memory。之所以是“随机存取”,是因为计算机能直接访问任意内存位置。辅助存储设备则通常要求顺序访问。换言之,计算机必须检索全部或至少大量存储位置,直至找到需要的数据项。
处理器也称中央处理单元,或者CPU是计算机的“大脑”。在广告中,厂家会说计算机用的是什么芯片。芯片指的就是处理器。处理器按程序指令操作,执行程序指定的计算。然而,处理器只是一个非常简单的“大脑”。它唯一能做的就是按照程序员提供的一系列简单指令进行操作。一般的处理器指令是:“将这个0,1序列解释成数字,将内存位置37的数字加到内存位置59的数字上,将结果放到位置43”。或者“读取输入的一个字母,用0,1序列对其进行编码,将这个编码放到内存位置1298”。处理器可执行加、减、乘、除,并可将数据从一个内存位置移动到另一个。它能将0,1序列解释成字母,并将字母发送到输出设备。处理器还具有重新排列指令顺序的基本功能。不同的计算机可能使用不同的处理器指令集。现代计算机的处理器通常都支持几百条指令。然而,如上文所述,每条指令执行的任务都是非常简单的。
软件
人一般不直接和计算机通信,而是通过操作系统和它交互。操作系统为计算机必须完成的不同任务分配计算机资源。操作系统实际是一个程序,或者是多个相互协作的程序,但更好的办法是把它想象成你的管家,负责管理家中的其他所有佣人,把你的要求传达给他们。如果希望运行一个程序,就要把包含这个程序的文件的名称告诉操作系统,操作系统会帮你运行它。如果想编辑一个文件,告诉操作系统文件名是什么,它会启动一个编辑器并加载那个文件。对于大多数用户,操作系统就是计算机。没有操作系统,大多数用户根本无法操作计算机。常用的操作系统包括UNIX,DOS,Linux,Windows,Mac OS,iOS和Android等。
程序是计算机需要遵照执行的一系列指令。如图1.3所示,计算机的输入由两部分组成:程序和数据。计算机按照程序中的指令操作,在这个过程中,会执行一些具体的处理。从概念上说,数据是向一个程序提供的输入。例如,如果程序要将两个数字加到一起,这两个数字就是数据。换言之,数据是程序的输入,而程序和数据共同构成了一台计算机的输入一般通过操作系统。任何时候只要向计算机提供了一个它必须遵照执行的程序,并为程序提供了一些数据,就称为要对那些数据运行程序,而计算机要对那些数据执行程序。“数据”一词还有更常规的含义。从广义上说,它意味着计算机可用的任何信息。狭义和广义的“数据”我们平时都在使用。
图1.3 程序运行简单示意图
高级语言
可以使用许多语言编写程序。本书将讨论C++编程语言,并用它编写程序。和其他大多数语言一样,C++也是一种高级语言。其他高级语言还有C,C#,Java,Python,PHP,Pascal,Visual Basic,FORTRAN,COBOL,Lisp,Scheme和Ada等等。高级语言在许多方面都类似于人类使用的语言,其设计宗旨是方便人们编写和阅读程序。高级语言包含的指令比CPU能够执行的简单指令要复杂得多。
计算机能理解的语言称为低级语言。在不同类型的计算机上,低级语言的细节也是不同的。一个典型的低级语言指令可能如下:
ADD X Y Z
它的意思是“将内存位置X的数字加到内存位置Y的数字上,再将结果放到内存位置Z处”。上述简单指令是用汇编语言写成的。虽然汇编语言已非常接近计算机能直接理解的语言,但仍要经历一次简单转换,才能真正被计算机理解。计算机要想遵照汇编语言指令行事,所有单词都必须转换成0,1序列。例如,单词ADD可能转换成0110,X可能转换成1001,Y转换成1010,而Z转换成1011。所以,执行上述汇编语言指令时,计算机实际执行的指令是:
0110 1001 1010 1011
不同机器使用的汇编语言指令以及它们转换成0,1序列的方式是不同的。
这种0,1形式的程序是用机器语言写的,那才是计算机真正理解的语言。汇编语言和机器语言差别不大,而且这种差别对我们来说并不重要。重要的是机器语言和高级语言比如C++的区别:用高级语言写的所有程序都必须翻译成机器语言,以便计算机理解。
编译器
将C++等高级语言翻译成机器语言的程序称为编译器。编译器是一种特殊程序,它的输入或数据是一个程序,输出的又是一个程序。为避免混淆,一般将输入程序称为源程序或源代码,编译器输出的程序则称为目标程序或目标码。码或代码一词常用于表示程序或程序的一部分。说到目标程序时,通常会使用目标码一词。现在,假定你希望运行自己写的一个C++程序。为了让计算机遵循C++指令,要采取以下步骤。首先,运行编译器,将C++程序作为数据提供给编译器。注意,在这种情况下,C++程序不被视为一系列要执行的指令。对于编译器来说,C++程序不过是一系列字符串。输出的仍是一系列字符串,即C++程序的机器语言版本。接着,要运行这个机器语言版本,向它提供平常我们以为是提供给C++程序的数据。如果有两台计算机,就更容易理解这一基本过程,如图1.4所示。但事实上,这个过程是在同一台计算机上完成的,只不过用了两次计算机。
图1.4 编译和运行C++程序基本过程
翻译和运行C++程序的完整过程比图1.4的“基本过程”稍微复杂一些。任何C++程序都会用到一些已编制好的操作比如输入和输出例程。这些操作已进行了编译,并生成了相应的目标码。它们等待着与你的程序的目标码合并,以生成一个完整的能够在计算机中运行的机器语言程序。在这个过程中,要由另一个名为链接器的程序将事先准备好的目标码与基于你的C++程序而生成的目标码合并。图1.5展示了编译器与链接器的交互。但在目前的大多数系统中,这个链接过程都是自动完成的。所以,一般不用关心链接问题。
编 译 器
编译器是一种特殊的程序,它能将高级语言程序比如C++程序翻译成机器语言程序,使计算机能直接理解并执行。
图1.5 运行C++程序之前的准备工作
链 接 器
C++程序的目标码必须与程序用到的例程比如输入和输出例程的目标码合并。合并目标码的过程称为链接,由名为链接器的程序完成。简单程序的链接过程可能自动完成。
自测题
1.计算机的5个主要部件是什么?
2.一个对两个数字进行相加的程序,它的数据是什么?
3.一个为学生分配字母成绩的程序,它的数据是什么?
4.机器语言程序和高级语言程序的区别是什么?
5.编译器有什么作用?
6.什么是源程序?什么是目标程序?
7.什么是操作系统?
8.操作系统的作用是什么?
9.你上这门课时所用的计算机运行的是什么操作系统?
10.什么是链接?
11.你用的编译器是否具有自动链接功能?
先驱人物 查尔斯巴贝奇与艾达奥古斯塔
第一台真正可编程的计算机是由英国数学家和物理学家查尔斯巴贝奇Charles Babbage设计的。巴贝奇在1822年前的某个时间开始这个项目,并将自己的余生都奉献给了它。虽然这台机器始终没有完成,但它的设计思想是计算机历史上的一个里程碑。我们对于查尔斯巴贝奇和他的计算机设计的认识,主要来自他的同事爱达奥古斯塔Ada Augusta Lovelace的著作。爱达奥古斯塔是诗人拜伦之女,后来晋封为伯爵夫人。许多人都认为爱达奥古斯塔是有史以来的第一位计算机程序员。她的一些观点在下一节开头引用至今仍然适用于计算机的问题求解过程。计算机不具备魔法,不能至少目前不能为我们遇到的所有问题都自动给出妥善的解决方案。计算机只能做程序员要它做的事情。虽然解决方案最终由计算机执行,但方案本身由程序员自己制定。所以在讨论计算机编程时,首先要讨论程序员如何制定解决方案。
1.2 编程和问题求解
分析机没有自主性。它能做我们操控它做的事情。它能跟着分析走;但无法预见到任何分析关系或定理。它的职责就是帮助我们做我们已知如何做的事情。
——爱达奥古斯塔,勒芙蕾丝伯爵夫人 1815—1852
本节介绍设计和编写程序的常规原则。这些原则并非C++特有,而是适合任何编程语言。
算法
开始学习自己的第一种编程语言时,很容易得出这样的观点:用计算机解决问题时,最困难的是如何将自己的思想转换成计算机能理解的语言。但实际并非如此。事实上,用计算机解决问题时,最困难的是找出解决问题的方案。只要有了解决方案,就能像例行公事那样将方案转换成需要的语言无论C++还是其他编程语言。所以,有必要暂时忽略编程语言,将重点放在解决问题的步骤上,用通俗易懂的话将各个步骤写下来,就像是要向人而不是计算机发指令。以这种方式表示的指令序列通常称为算法。
用于解决问题的一系列准确的指令称为算法,通常也可称为方法、指示、过程和例程等。指令可用编程语言或自然语言表示。我们的算法用中文和C++编程语言来写。计算机程序就是用计算机能理解的语言来表示的算法。所以,“算法”一词比“程序”更常规。然而,说一个指令序列是算法时,通常是说这些指令要用中文或英文描述。相反,如果是用编程语言描述的,就应该使用更具体的