看板CompBook
标 题C++ Primer 答客问 (45) - 三刷修订
发信站清华资讯(枫桥驿站) (Sat Mar 25 22:40:45 2000)
转信站Ptt!bbs.ee.ntu!freebsd.ntu!news.cs.nthu!maple
C++ Primer 答客问 (45) - 三刷修订
侯捷
[email protected]
2000.03.25 第一次发表於
清大.枫桥驿站(140.114.87.5).电脑书讯版(Computer/CompBook)
本文将於日後整理於 侯捷网站/侯捷译作/C++ Primer 中文版/答客问
侯捷网站:www.jjhou.com
----------------------------------------------------------------
《C++ Primer 中文版》目前正在进行第三刷(印量 5001~8000)。
本次续将发现的各种错误修正。
原本我的习惯是,拿到新书後,确定已经依照我的要求订正妥当,
才将修改之处公布给读者知道。不过既然最近有读者询问,我就
稍稍提前公布。
p.s. stella & simon: 新刷若未如计划修正,而此资料已公布,
那就只好提头见读者罗 :)(我们一起)
===========================================================
书籍内容更正,有两种作法,一是在网际网路上做个专属勘误网页,
让大家上去看。这是比较即时的作法。而更理想更负责的作法是:
不但有勘误网页,并且在新刷中予以更正 -- 如果有新刷的话。
不过,理想与现实之间需要一点协调。书籍的制作是这样的,
制版与印刷时,是以台(8 或 16 页)为单位。因此,每换一页,
同台的各页统统要换过。这便造成印制成本的大量增加。
以前,我从不考虑成本,只要我认为书籍内容有修改必要,
即使只是某个字词用得不甚理想,我都会请出版社更新。
出版社也都全力配合(这一点让我非常感谢)。
慢慢地,我的行事不再这麽霹雳,我觉得我多少也要站在
出版社的立场想想。所以我打算,如果是关系到对错正误的
根本性问题,我便一定在新刷修正。如果是易判别的错别字
或排版误失或用词不很恰当…等等,我便先在勘误网页上明载,
但不求立刻於新刷中更正。直到收集来的这类误失较为密集了,
才一并於下一刷修正。
哪些是新刷已修正的,哪些是暂请读者自行动手更改的,
我会在勘误网页上很清楚地说明。
这是个便宜法门,请读者见谅。
书籍应该在出版前就详细检查,以完美之姿出现。但是完美很难达到。
对於下列大大小小轻重不等的误失,我谨向读者说抱歉。
ps1 由於出版商对《C++ Primer 中文版》的每一刷印量颇巨,
导至每一刷的更迭周期比较慢。如果您想等待下列所有大大小小
轻重不等的误失在印刷品上更正完毕,可能需要等上好一阵子
且无可预期。很抱歉。
ps2 由於侯捷网站的新内容出了点问题(至今我还不知道怎麽修复),
无法把这份重要的勘误资料放在站上,因此暂以 BBS/News 来传播。
欢迎(敬请)广为流传。
================================================================
以下为二刷更正内容:
(注意,Lm 表示第 m 行,L-n 表示倒数第 n 行)
■导读 p23
原文:
template <typename T>
T func( T p1, T p2, int p3 ) // ( T p1, T p2, int p3 ) 称为 template parameter
list
{ /* ... */ } // p1, p2 称为型别参数(type parameter)
// p3 称为非型别参数(nontype parameter)
更正:
template <typename T> // <typename T> 称为 template parameter list
T func( T p1, T p2, int p3 ) // 其中 T 是 template type parameter(型别参数)
{ /* ... */ } // 另有所谓 template nontype parameter(非型别参
数),
// 本例未出现。
■p36 L-2
原文:当它後面紧跟着一个 class 名称
更正:当它紧跟着一个 class 名称後面
感谢:黄向阳先生
■p106 L17(原书笔误)
原文:int *&ptrVal2 = pi;
更正:int *&refPtr = pi;
感谢:黄向阳先生
■p342: L-4(原书笔误)
原文:以下示范利用 rswap() 交换两个指标
更正:以下示范利用 ptrswap() 交换两个指标
■p496: L13
原文:inline 或 extern 修饰词应该放在 template 参数列之前,而非…
更正:inline 或 extern 修饰词应该放在 template 参数列之後,而非…
■p1130: copy_backward() 下的第二段文字(原书错误)
原文:
例如,给予数列 {0,1,2,3,4,5},我们可以复制最後三个元素 (3,4,5) 到
最前三个元素 (0,1,2) 身上,作法是将 first 设定为元素 0 的位址,
last1 设定为元素 3 的位址,last2 设定为元素 5 的下一个位址。
於是元素 5 会被指定到原来的元素 2 身上,元素 4 会被指定到原来的元素 1 身上,
元素 3 会被指定到原来的元素 0 身上。最後的结果是 {3,4,5,3,4,5}。
更正:
例如,给予数列 {0,1,2,3,4,5},我们可以复制最前三个元素 (0,1,2) 到
最後三个元素 (3,4,5) 身上,作法是将 first 设定为元素 0 的位址,
last1 设定为元素 3 的位址,last2 设定为元素 5 的下一个位址。
於是元素 2 会被指定到原来的元素 5 身上,元素 1 会被指定到原来的元素 4 身上,
元素 0 会被指定到原来的元素 3 身上。最後的结果是 {0,1,2,0,1,2}。
================================================================
以下为三刷更正内容:
(注意,Lm 表示第 m 行,L-n 表示倒数第 n 行)
■p318 最後一段第二行(误译)
原文:这种作法之所以能够成功,是因为这些 containers 保证其
元素实体会以连续的方式出现(存在)。
更正:这种作法之所以能够成功,是因为这些 containers 保证其
键值相同的元素会连续出现(存在)。
■p322 最後一段第二行(修润)
原文:我们称 stack 为一种所谓的 container adapter,因为它
在底层的 container 集合体身上课徵 stack 抽象性质。
更正:我们称 stack 为一种所谓的 container adapter,因为它
系利用底层各类型 container 加工完成 stack 抽象性质。
■p495, L4(原书笔误)
原文:// ok: Type used many times in template parameter list
更正:// ok: Type used many times in function parameter list
感谢:kylin
■p501, L12(中译本误植)
原文:min2() 的第一个函式参数是个型别为 *Type 的指标。
更正:min2() 的第一个函式参数是个型别为 Type* 的指标。
■p503, L-5(原书笔误)
原文:上述的 template 引数 T 从第一个函式引数中推导得 int,
又自第二个函式引数中推导得 unsigned int,因此 template 引数推导失败。
更正:上述的 template 引数 T 从第一个函式引数中推导得 unsigned int,
又自第二个函式引数中推导得 int,因此 template 引数推导失败。
感谢:leetron
■p565, L7(原书笔误)
原文:Exception declaration 是函式介面的一部份,所以它必须...
更正:Exception specification 是函式介面的一部份,所以它必须...
■p576, 最上(中译稿漏印,缺少两个右大括号)
原文: // ...
更正: }
// ...
}
注意:我在本书第三刷(3/p)中将 p575 和 p576 相邻处的 layout 做了
一点点挪移,所以第三刷的读者在 p576 最上所见并非上述那样子。请勿疑虑。
■p595, L-5
原文:当然,「令一个 non-const iterator 指向一个 const iterator」总是可以的。
更正:当然,「将一个 non-const iterator 指派给一个 const iterator」总是可以的。
■p596(原书笔误)
说明:本页下方有三点,讨论 back_inserter, front_inserter, inserter.
并均利用 unique_copy() 做为使用范例。每一个 unique_copy() 都
遗漏了最後的右大括弧。
更正:请为 unique_copy() 加上最後的右大括弧。
感谢:Megadeth
■p652, L-1(中译稿漏印,少了最後一行)
原文:有着以下的型别:
更正:有着以下的型别: int (Screen::*)()
■p731, 第一段(中译误失)
原文:
举个例子,如果我再次修改 Account class 的定义,令 _name 的型别为 string,
那麽预设的 memberwise 指派动作:
newAcct = oldAcct;
就会被编译器唤起,犹如编译器为我们产生了以下的 copy assignment 运算子:
更正:
举个例子,如果我再次修改 Account class 的定义,令 _name 的型别为 string,
那麽当:
newAcct = oldAcct;
预设的 memberwise 指派动作就会被编译器唤起,犹如编译器为我们产生了
以下的 copy assignment 运算子:
■p915, 第二段文字,第一行(译笔不佳,重译)
原文:一个 derived class constructor 只能合法地唤起其
「直接 base class」的 constructor
更正:一个 derived class constructor 能够合法直接唤起的 construtor 只有其
「直接 base class」的 constructor
■p915, 17.4.4 的标题(修润)
原文:17.4.4 惰式错误侦测(Lazy Error Detection)
更正:17.4.4 缓式错误侦测(Lazy Error Detection)
注意:请同时修改
p.ix, 目录
p.916, L6
p.981, 18.3.2 标题前两行
p.984, L-6
p.1224, 索引
讨论:我想,译为「缓式」可能比译为「惰式」更符合华人用语。在 Scott Meyers
的《More Effective C++》item17 "Consider using lazy evaluation" 中,
对於 Lazy evaluation 有深刻的解说,并提出一个对应词:eager evaluation。
我把 eager evaluation 译为「急式评估」。
■p941, 17.5.8 标题(误译)
原文:虚拟函式、虚拟解构式 constructor、虚拟解构式 destructor
更正:在建构式(constructors)与解构式(destructors)中呼叫虚拟函式
注意:请同时修改目录 (p.x)
■p1006, L-13(译笔不佳,重译)
原文:一旦成为 base class,class template 必须完整列出其参数列。
修改:欲令一个 class template 扮演 base class 的角色,我们必须完整列出其参数列。
■p1045 19.2.7 标题(笔误)
原文:19.2.7 Constructors(解构式)和 Function try Blocks 的关系
更正:19.2.7 Constructors(建构式)和 Function try Blocks 的关系
感谢:leetron
注意:请同时修改目录 (p.x)
■p1126, adjacent_difference 内文第二行(误译)
原文:给予数列 {0,1,1,2,3,5,8},新数列的 first 元素是
原数列的 first 元素的拷贝:0。
更正:给予数列 {0,1,1,2,3,5,8},新数列的第一个元素是
原数列的第一个元素的拷贝:0。
■p1126, L-15, p1127, L9(原书错误)
说明:这两行出现的 times,是某 function object 的旧名称,
在 C++ standard 中已改名为 multiplies. 见 p590
更正:将这两行出现的 times<int> 改为 multiplies<int>
■p1127, adjacent_find() 第二版本规格,最後一行(原书错误)
原文:ForwardIterator last, Predicate pred);
更正:ForwardIterator last, BinaryPredicate pred);
■p1128, binary_search() 第二版本规格,缺一行(原书遗漏)
原文:bool
binary_search(ForwardIterator first,
ForwardIterator last, const Type &value,
Compare comp);
更正:请在 bool 前面加上一行
template <class ForwardIterator, class Type, class Compare>
■p1149, inner_product() 规格说明最後一行(原书错误)
原文: (2+1) - (3+2) - (5+3) - (8+4)
更正:- (2+1) - (3+2) - (5+3) - (8+4)
■p1166, L9, L20(原书错误)
■p1167, L1, L3 (原书错误)
说明:这四行出现的 times,是某 function object 的旧名称,
在 C++ standard 中已改名为 multiplies. 见 p590
更正:将这四行出现的 times<int> 改为 multiplies<int>
■p1177, rotate() 规格说明第一行(原书错误)
原文:rotate() 会将 [first,middle) 范围内的元素搬移到 container 尾端。
更正:rotate() 会将 [first,middle) 范围内的元素搬移到 last 所指位置。
■p433, p434, p453, p454, p767, p769, p770, p771, p774, p781, p790,
p849, p863, p865, p866, p881, p898, p911, p914
字体变小,制版不当(做了缩版动作)。第三刷已重新制版。
================================================================
以下暂请读者自行更正:
(注意,Lm 表示第 m 行,L-n 表示倒数第 n 行)
■导读p7 L9(错别字)
原文:以译者的技术能力来抚平可能出现的阅读上的坎砢崎岖。
更正:以译者的技术能力来抚平可能出现的阅读上的坎坷崎岖。
感谢:whizzkid
■导读 p23, L-6
原文:以下造成上述 function template 产生出
函式实体 func(float, float, int);
更正:以下造成上述 function template 产生出
函式实体 double func(double, double, int);
■前言p.xviii, L9(误译)
原文:最後我要说,当一个人写了一本书,他决定略去的东西,
往往和他决定涵盖的东西一样重要。
更正:最後我要说,当一个人写了一本书,他决定略去什麽东西,
往往和他决定涵盖什麽东西一样重要。
■p39 L2(原书笔误)
原文:{init(rhs.size, rhs.ia);}
更正:{init(rhs._size,rhs.ia);}
感谢:chlin, Aua
■p46 中间偏下(中译本笔误)
原文:(我们将在第17章...
更正:此段最後请加上小括号
感谢:黄向阳先生
■p108, L10
原文:
如果由右往左阅读上述定义,我们会发现,pi_ref 是个 reference,
代表一个指标,此指标指向一个型别为 int 的 const object。
但是我们的 reference 实际上却未被用来代表一个常数,而是被用来
代表一个非常数指标(该指标指向一个常数 object)。
更正:
如果由右往左阅读上述定义,我们会发现,pi_ref 是个 reference,
代表一个指标,此指标指向一个型别为 int 的 const object。
我们的 reference 代表的不是一个常数指标,而是一个非常数指标,
指向一个常数 object。
■p125 练习 3.25(原书笔误)
原文:bool is_equal( const int*ia)
更正:bool is_equal( const int* ia) 请在 ia 之前加一空格
感谢:黄向阳先生
■p125 页眉位置
说明:页眉位置跑掉了
■p155 L6(原书错误)
原文:while( ix_vec < 10 )
更正:while( ix_vec < 9 )
感谢:李俊德先生
■p183 L3(错别字)
原文:就某种意义而言,这说明了 C++ 语言一个自相矛顿的基础议题。
更正:就某种意义而言,这说明了 C++ 语言一个自相矛盾的基础议题。
感谢:whizzkid
■p183 L7(错别字)
原文:Standard C++ 引入这些转型运算子以强调(鲜明标示出)这个矛顿
更正:Standard C++ 引入这些转型运算子以强调(鲜明标示出)这个矛盾
感谢:whizzkid
■p209 练习5.7 (d) 第一行(原书笔误)
原文:int ival=512 jval=1024, kval=4096;
更正:int ival=512, jval=1024, kval=4096; (原行少一个逗号)
■p242 L-4(笔误)
原文:...,後面紧跟着一串以中括号为界的参数。
更正:...,後面紧跟着一串以角括号为界的参数。
感谢:rago
■p468, 第二大段程式码的第五行(注解)出现一个中文乱码
原文:potentially dangerous depending on i掇 value
更正:potentially dangerous depending on i's value
感谢:edward
■p504, L-1
原文:根据各对应之「函式引数」所推导出来的「template 引数」,结果一定相同。
更正:根据各对应之「函式引数」所推导出来的「template 引数」,结果必须相同。
■p694, L6(原书笔误)
原文:Account *pacct;
更正:Account *pact;
■p694, L9(原书笔误)
原文:pact->Acct.Account::Account(
更正:pact->Account::Account(
■p709, 练习14.8, L4(原书笔误)
原文:Accout acct;
更正:Account acct;
■p889, 练习17.1 之前两行(错别字)
原文:物件导向程式设计的主要形帽便是...
更正:物件导向程式设计的主要形貌便是...
■p1015~1030(装订颠倒)
少部份书品在这些页次上装订颠倒。这是装订厂的误失,请向经销点
重换一册。如经销点不愿配合,请向
[email protected] 反应,
或向
http://www.gotop.com.tw 反应。
==================================================================
★英文 dimension 一词用於阵列有两义:(1) 维度 (2) 尺度(元素个数)
我在翻译过程中一时拘泥,译得不好。现重新检讨如下(抱歉,页数颇多):
■p24: L-13
原文:阵列的名称是 fibon。这是一个整数阵列,维数为 9。
更正:阵列的名称是 fibon。这是一个整数阵列,尺度(元素个数)为 9。
■p24: L-6
原文:最後一个元素,我们应该把维数减 1 做为索引值
更正:最後一个元素,我们应该把尺度(元素个数)减 1 做为索引值
■p28: L-9
原文:new 算式的第二个版本配置出一个特定型别和特定维数的阵列。
更正:new 算式的第二个版本配置出一个特定型别和特定尺度(元素个数)的阵列。
■p34: L7
原文:我把阵列的维数指定给 array_size。
更正:我把阵列的大小指定给 array_size。
■p114: 最後一段文字
原文:
阵列的定义系由型别符号、识别名称、维度(dimension)三者构成。
维度以一个中括号表示,指出阵列之中有多少元素。阵列的维度大小必须
大於或等於 1。维度值必须是一个常数算式,也就是说,它必须能够在
编译时期便被编译器核定(evaluate)其值。换言之一个 non-const
变数不能够用来指定阵列的维度大小。
更正:
阵列的定义系由型别符号、识别名称、尺度(dimension)三者构成。
尺度以一个中括号表示,指出阵列之中有多少元素。阵列的尺度必须
大於或等於 1。尺度必须是一个常数算式,也就是说,它必须能够在
编译时期便被编译器核定(evaluate)其值。换言之一个 non-const
变数不能够用来指定阵列的尺度大小。
■p115: L2
原文:只能够在执行时期完成,所以它不能够用来指定阵列维度。
更正:只能够在执行时期完成,所以它不能够用来指定阵列尺度。
■p115: L-13
原文:面对一个明白初始化的阵列,你不需要再指定其维度,
更正:面对一个明白初始化的阵列,你不需要再指定其尺度,
■p115: L-9
原文:如果维度被明白指出,那麽串列中的元素个数就不能够超越该值,
更正:如果尺度被明白指出,那麽串列中的元素个数就不能够超越该值,
■p116: L1
原文:ca1 的维度值是 3 而 ca2 的维度值是 4。
更正:ca1 的尺度(元素个数)是 3 而 ca2 的尺度是 4。
■p162: L8
原文:像是阵列的维数,或是 template 的 nontype 参数。
更正:像是阵列的尺度(元素个数),或是 template 的 nontype 参数。
■p415: L13
原文:以 new 算式配置获得的阵列,其维度可被指定为…
更正:以 new 算式配置获得的阵列,其尺度(元素个数)可被指定为…
■p616: L6
原文:也应该允许使用者在执行时期设定萤幕的实际维度。
更正:也应该允许使用者在执行时期设定萤幕的实际尺寸。
■p617: L-14
原文:使用者决定让所有的 Screen class objects 维度为 80 x 24,
更正:使用者决定让所有的 Screen class objects 尺寸为 80 x 24,
■p1079: L17
原文:其中的 bufSize 便是字元阵列 buf 的维度。
更正:其中的 bufSize 便是字元阵列 buf 的尺度(元素个数)。
■p1079: L22
原文:如果 buf 的宣告并未指定维度:
更正:如果 buf 的宣告并未指定尺度(元素个数):
--- the end
--
※ Origin: 枫桥驿站<bbs.cs.nthu.edu.tw> ◆ Mail: [email protected]