C++ Primer读书笔记1(经典收藏)

C++ Primer 读书笔记
注:本文 www.Eachfun.com
          (整理说明:本资料是我在网上无意间找到的,读起来感觉不错,但由于原文是每章一个网页的格式,读起来不是很习惯,而且也不方便保存,所以我花了 2 个多小时的时间将所有网页的内容综合整理了一下,但最后才发现,文章的顺序颠倒了,所以各位如果愿意阅读本文的话,请从后面向前读,每个红色“标题”代表一章,如有不便还请各位见谅,或到原文网站阅览)
标题: 转换 转换
于我 3+1.5=4.5 。但是 算机来 两个数的相加可不 这么简单 。因 3 3.0 是不同的数据 型, 3.0 1.5 是可以相加的, 3 却不能与 1.5 相加。于是, C++ 上面的表达式 ,有必要 其中一个(或两者) 转换
  因 为这 转换 的,也就是 说这 转换 程序 知道,那 ,系 就不能必 失, 失指的是精度。 了不 失精度,数据 是向精度高的 转换 。惟一的例外是当某个 量用作条件 ,它被 转换为 bool 型。
   术类 型的 转换 这样 的:所有比 int 小的都 转为 int unsigned int ,即使没有必要也 这么转 。原因很 简单 ,因 int 度正好等于字 CPU ,一次 理一个字是最快的。如果 int unsigned int 无法达到要求, long double 化。
  如果 一个 转换 能不造成 失,那自然是好事。可是世 的事 有不随人愿的 候。 于同一 术类 型,其 signed unsigned 所能表达的范 是一 大,但却是互不重叠的两个范 。就像 妇联 工会 ,往哪 边转换 都可能会 失。 是无法解决的 问题 ,所以,在 VC 中, 试图 int unsigned int 示警告。
  奇怪的是,据我 测试 ,在 VC++.net 中,只有 “<” “>” 候才会 示警告,而 “==” “!=” 候却不 示警告。 实际 两个比 也会有同 问题产 生,比如以下代
int a = -3;
unsigned b = 4294967293;
if (a == b) cout << "yes" << endl;
   测试 运行以上代 发现 表达式 a==b 值为 true 是从 int 转为 unsigned int 程中的副作用, 个副作用我 们应该 知道,但是 VC++.net 行任何警告似乎也有些与理不通。 —— 道我 关闭 了某些警告?
  其它 转换还 包括数 转换为 、算 术值 用作条件 时转换为 bool ,枚 转换为 整数,非 const 转换为 const 象等。其中枚 举转换为 整数没什 要提的,枚 举值 本来就是整数的 名,非 const 转为 const 象只是 临时 声明它的保 护级别 ,通常用于作 参数 传递时
 
 
标题: :内存管理之 new delete
博士曾将内存管理比 喻为 雷区 (《高 C++/C 程指南》第 44 ),内存管理 这块难 ?恐怕不好 会者不 难难 者不会 嘛。但是 内存管理 这块难 以成 会者 应该 是没有 的。
  程序 时时 刻刻与内存打交道,只不 以往我 不用考 ,甚至不用知道。所以,所 内存管理 ,是特指堆内存。
  如果把堆内存和 内存的使用放在一起考 ,可以降低 内存管理恐惧。
  一、内存的分配:
   int i(100);// 上分配内存
   int *pi = new int(100);// 堆上分配内存
  以上两 分配,都使用了 100 初始 值进 行初始化,如果是 类对 象的分配,它 们还 可以指定使用哪个构造函数,比如:
   CString s(s1);// 上分配内存
   CString *ps = new CString(s1)// 堆上分配内存
   里的 s 可以是 char* ,也可以是另一个 CString 象,它的 型将决定上面 两行 用哪一个构造函数。
  在 里,有一点要特 别说 明,如果要使用默 造函数, new 句后面可以用空括号 ,而 内分配的 句切不可用空括号 。如果写成 “CString s();” 并不是定 一个 CString s ,而是定 一个返回 值为 CString 的函数 s
  上面两 分配,也都可以分配 象数 ,不同的是,用 new 操作符在堆内存分配数 组时 ,只能 用默 构造函数。而在 上分配却可以指定 象成 的初始 。如:
   int a[3] = {1,2,3};// 上分配内存, int 可以 成其它 型名,后面的初始 可作相 应调 整。
   int *p = new int[3];// 不能指定 三个 象的初始
  二、内存的 访问
   内存可以通 过对 访问 ,也可以通 针访问 ,堆内存通 针访问 。方法完全相同。
  三、内存的 放:
   内存在 象作用域 束后自 动释 放,堆内存要用 delete
   delete pi;// 放内存
   delete []p;// 象数
   象数 ,那个空的 [] 不可以 ,否 将只 放数 的第一个元素。 致内存泄露。
  有了以上 比,堆内存似乎没有了任何 度。那 内存管理的玄机究竟在哪儿呢?在 行内存分配与 放的 候,有几个注意点要 住:
   1 new 操作有可能失 ,当系 无法分配需要的内存 块时 ,将返回 NULL ,所以在 new 操作之后,要立即判断 pi 是否 NULL
   int *pi = new int(100);
   if (pi = NULL) {...}
   2 、堆上分配的内存必 delete ,而且只可以 delete 一次。 了保 内存只被 delete 一次, 请务 delete 以后立即将指 针设为 NULL
   delete pi;
   pi = NULL;
   “pi=NULL;” 不是必 的,但 是个好 习惯 。将指 针设为 NULL 既可以防止 继续读 内存,也可以防止再次 内存。
  老的 C 程序 可能忘不了 malloc free 函数,它 也可以 行内存的分配与 放。但是 C++ 代它 落伍了。它 只是按 求的字 行分配,而不管你用 这块 内存来干什 这样 做,就等于放弃了 类对 象的构造与析构。 于很多 这样 做是很危
 
 
标题: 合性和求 值顺
,我能熟 背出 先乘除,后加减 ,之于 C++ 列出的整整 19 又包含若干个操作符,我 是看了就 麻。以我的 性, 连军 旗里哪个大哪个小都背不出来, 几十个操作符 —— 了我吧。
   住林 博士的 如果代 行中的运算符比 多,用括号确定表达式的操作 序,避免使用默 (《高 C++/C 程指南》第 26 这样 做最直接的作用是不用 记忆 复杂 了,不用 记忆 并不是因 为懒 ,而是 了更清晰。 竟程序不只是 编给计 算机运行的,当我 们处 在一个多人 作的 体中 ,程序的清晰度和精确性比性能要高得多。再 ,多加几 括号是不影响运行效率的。
   合性和求 值顺 序是容易混淆的两个概念。 一个操作符都 定了 合性,但是只有极少数操作符 定求 值顺 序。 合性是 如果有多个同 级别 的操作符, 些操作数 如何分 。比如 “1+2+3” 究竟分成 “(1+2)+3” “1+(2+3)” 没有区 ,但不等于所有操作符都不 生区 。即使不 生区 算机 竟是 算机,它只能按死的 范做事,于其 它灵 活机制, 不如 定了 合性 它遵守。
   C++ 只有四个操作符 定了求 值顺 序,它 “&&” “||” “?:” “,” 四个操作符并不 。反 住其它操作符也不 的是在写程序中是否有 个意 。那 多网友 讨论 “j = i++ + i++ + i++;” 果,正 明了 有好多人不了解 未定 的威力。如果不小心使用了依 于未定 程序的 句,将是一个不容易 发现 并改正的 问题 比如 “if (a[index++] < a[index]);”
 
 
标题: sizeof 和逗号操作符
sizeof 成操作符可能有些不合 习惯 ,因 sizeof 的用法与函数没区 。但是 sizeof 与函数有着本 的区 :它是 编译时 常量。也就是 ,在程序 编译时 ,就会求出它的 ,并且成 程序中的常量。
   sizeof 本身比 较简单 ,惟一要提的就是它 名和指 针进 行操作的 果。
int a[10];
sizeof(a);
   操作返回的是数 所有元素在内存中的 总长 度。但是如果 针进 行操作,返回的 是指 本身的 度,与指 所指 型无
  正因 名与指 有着千 系,所以有 个特性会 人摸不着 头脑
int function(int a[10])
{
  sizeof(a);
  ...
}
  以上 sizeof 返回的不是数 所有成 的大小,而是指 的大小,因 在参数 传递 中弱化
  逗号操作符除了在 for 句中 用以外,我没 发现 在哪儿 有用 。因 在一般情况下,逗号改成分号肯定是可以的,在 for 句中因 分号的作用另有定 ,所以不能随便改。 才有了逗号的用武之地
 
 
标题: :条件操作符
得条件操作符的存在就是 if-else 句。第一,它与 if-else 句的功能完全一致;第二,它 然是一行 句,但是它 定了求解 序, 序保 了有些表达式不被求
  条件操作符是有一定的危 性的,危 的原因在于它的 底, 容易漏掉括号。它的 级仅仅 高于 赋值 和逗号运算符,也就是 ,只有在与 赋值 或逗号共存 ,才可以免去括号,其它情况下都得加上括号。漏加括号的 BUG 是很 难发现 的。
  比如 “cout << (i < j) ? i : j;” 句的 实际 作用是将表达式 “(i 值输 出,然后 测试 一下 cout 的状 << 操作符的返回 cout ),整个表达式的 不管是 i j ,都被
 
 
标题: :箭 操作符( ->
操作符是 C++ 明的全新操作符,但却不是 C++ 才用到的功能。早期的 C 然没有 ,却有 构体,也允 有指向 构体 象的指 。不同的只是没有 “->” 个符号来 化操作。 到底, “->” 的出 只是代替原来就可以 实现 的功能。
  引用: C++ 包含点操作符和解引用操作符的表达式提供了一个同 义词 :箭 操作符( -> )。
  笔 一同 义词 的出 ,不 仅仅 使程序 化而且更易于理解,更重要的是,它降低了出 的可能性。出什 么错 呢? 就跟操作符的 了:
p->a();
(*p).a();
  以上两行等价,但是第二行却很容易写成 “*p.a();” ,由于点操作符的 高,就成了 “*(p.a());” 里至少包含了两个 错误 :一是 p 不是 象,点操作无效;二是 试图对类 解引用(只有当 返回指 才有效)。
  也 有人要 了,第一个 错误 经导 致了 编译 不通 第二个 错误 干什 这样 理解就 了。 VC++ 程序 提供了一个 十分 大的 ,其中有些 象,既可以 行点操作也可以 行解引用操作的,如果上例中的 p 是那 种类 象,而且 p.a() 好又返回指 ,那 上面 句将可以通 过编译 ,最 终换 找的 BUG
   住,尽量多用箭 操作符
 
 
标题: ++ 的陷阱
自增和自减符作符是如此常用,以至于没有必要提了。但是任何一本 都会下重手来提它,原因是它 简单 ,却含有玄机。
   到前自增和后自增 ,几乎所有的 都是 这样讲 的:用 “j = i++” “j = ++i” 比,告 诉读 i 都增了 1 ,但是 j 却不一
   也没 法,因 为绝 大多数 ++ 时还 没有提到 表达式的 个概念,有些 本可能从 到尾都不提。 “j = i++;” ,它是一个表达式没 ,但是等号右 也是一个表达式, 于表达式 “i++” ,它是有 的, 表达式的 值赋 予了 j ,而整个表达式也有一个 ,只是 弃了。 推: “i = j = k = 1;” 句中 独的 “1” 就是一个表达式,叫常量表达式,它的 就是 1 ,它 k “k=1” 个表达式也有 ,它的 就是 k ,它 j …… 最后 i 赋值 的表达式也有 ,它的 就是 i 弃。
  弄明白了 表达式的 后,就可以科学地 “++i” “i++” 了,因 为这 两个表达式的 这样 的:前置自增 / 减表达式的 是修改后的 ,后置 则为 修改前的
  那 ,在不 心表达式的 —— 即只是 量自增或自减一下 —— 究竟用哪个好呢?当然是前置好,因 前置只要用一个指令 行一下自增自减运算,然后直接返回即可。而后置却要先保存好 个初始 ,再自增减,然后再返回以前保存的 。写 操作符重 的程序 员应该 更能体会 里面的区
   “++i” “i++” 这样简洁 ,所以它 “i = i + 1;” 要美得多,所以 简洁 就是美 。但是,在美的同 ,一个美 的陷阱正在招手,程序 员们 理解并小心。
   “if (ia[index++] < ia[index])” 这样 的表达式是危 的。前文中已 提到了, C++ 中只有极少的几个操作符是 定了 值顺 序的, “<” 号没有 定,那 两个数要比 大小,系 究竟先求前者 是后者?如果先求前者,那 求后者的 index 有没有增一?
   常在 论坛 上看到有人 讨论 “j = i++ + i++ + i++;” 果, 有人把自己的 出来 证实 自己的理 正是初学者令人悲哀与同情的地方: 应该 好好掌握的知 没有足 情,却把一腔 血放在 些无 须讨论 话题 上, C++ 初学者要走的路不 仅长 ,而且充
 
 
标题: :回 十几年前的 程入
本来不想 为这 段写 读书 ,不 突然想起十几年前的一件趣事来, 下来吧。
   1993 年的 候,学校 开设 的是 BASIC 言。 于当 时连电脑 都没看 一眼的我 ,学校 开设这样 ,真是 无比感 。我至今仍然感 我的母校,在片面追求升学率、大量 减副 的全局下,我的母校居然 开设 了音 、美 技等一系列副之又副的 这让 我至今 忘。而令一方面,我今天能 在程序界打拼,完全是从那 始陪 趣。如果我的高中没有 开设这门课 ,我未必就不 入程序界,但是入 至少要 三年。
   三年, 我学的 西少之又少, 于整个 BASIC 皮毛都不如,而且学校只提供了一次上机机会, 的是 机与 机。我所 调试 程序 是在自己的小霸王学 机上 行的。但是,在 电脑 没有普及的年份,懂得一点点就是很先 的了。 入大学后,堂堂一个大学的班 ,居然只有两个人碰 过电脑 ,大家的基 可想而知。在同学 拼命学 DOS 命令的 候,我已 遥遥地走在了前面。之后学 True Basic 自然一日千里,之后自学 VB 、自学 C 也就 理成章。如果我的高中没有 开设这门课 ,我未必就不 入程序界,但是我在 大学的 一段 时间 肯定会 与其他同学一起拼命 DOS 命令。要知道,其他同学至所以学得比我慢,并不是比我笨,而是没有 习惯电脑 的思 模式。
   该说 赋值 操作符 了。高中 开设 BASIC ,其 本是不到半厘米厚的小 。但是我 手地提前 阅读 了。 得一知半解就去做后面的 习题 发现 一句 “P=P+1” ,心想: 可能嘛? P 可能等于 P 加一呢?移 一减,不就相当于 0=1 ?一定是 上印 了。于是,我将其中一个 P 改成了 R ,而且是用黑 笔描的。我描得是如此 致,以至于根本看不出那个 R P 改的。等到老 师讲 候,我 然已 懂了 “=” 与数学上的 “=” 不一 ,但是由于把 P 看成了 R 这题还 是做 了。
  当 的情况是 这样 的:老 喊了几个同学上去做 ,没有一个会。老 师说 有没有 会做的?主 上来? 好几个同学立即喊我的名字,把我逼上去了。 果我 这么 一做就做 了。老 了我的勇气,但是同学却 然平 捧着 不放,原来也是个
   赋值 操作符就是在那个 我留下深刻印像的,那天我知道了, “=” 号不表示左右相等。
   赋值 操作符也比 较简单 ,理解了它的用法就好了。 C++ 至所以有了 赋值 操作符以后 赋值 操作符,不 仅仅 化代 可以加快 理速度。 “i=i+j” “i+=j” 相比,前者的 i 了两次。不 点性能差 别对 整个程序性能来 不大。 有一个区 就是 方面的了。 “i*=j+1” 如果不写成 赋值 ,就要加上括号: i=i*(j+1)
 
 
标题: 系、 逻辑 和位操作符
系操作符本身没什 好提的,它 与我 逻辑 ,所以不 理解。有两点可以略提一下:
  一、因 ASC 字符中没有 “≥” 些符号,所以只好用 “>=” 代替。于是 生了 BASIC C++ 的两 不同符号集: BASIC “<>” 表示不等于, C++ “!=”
  二、程序 设计时 不能用 “if (i < j < k)” 这样 的写法。原因很 简单 ,因 为这种 写法另有含 ,或者 正因 不能 这样 写,才 给这种 写法另外 了一
   BASIC C++ 逻辑 操作符也有完全不同的写法, BASIC 用比 关键 “And” “Or” C++ “&&” “||” 也没什 住就行了。
   逻辑 操作符中的 “&&” “||” C++ 准中 数不多的指定了求 值顺 序的操作符(除此以外 有条件操作符 “?:” 和逗号操作符 “,” 于求 值顺 序,后面 将提及)。 这样 定惟一的缺点是需要 外的 记忆 是很明 的:它可以 的操作 得不危 。如 “while (i0)” “Array[i]” ,指 越界是很可怕的,但是 “&&” 操作符的求 值顺 序保 了指 不越界。从另一方面 ,要保 不越界,就必 须记 操作符的求 值顺 序(不然就只能分成两个 句写 )。
  又要提到 bool 的比 了, “if (i < j < k)” 实际 就是 行了 bool 的比 。本 解的 候, 然提到了 k 与整数 0 1 做比 ,但是我宁可提醒大家不去 个。 bool 只有 true false 两个 ,比 1 0 要好得多,因 为虽 false 就是 0 ,但是 true 却不 1
   C++ 中如果只有 逻辑 操作符也就算了,它偏 “&” “|” 这样 的位操作符。而位操作正是 BASIC 不提供的功能。 初学 C/C++ 的人 来了 度。 点不在于理解,而在于 记忆 。位操作符的作用是 行某一 Bit 位的 定,在一个字 节掰 成八份用的年代,它非常常用, 比如 Turbo C 中的屏幕 置,就是 3 位表示背景色、 4 位表示前景色、一位表示 闪烁 ,用一个字 完全存放了屏幕字体的信息。 在的海量存 与高速 理中,大可不必 这么节约 了(从 理速上看,非但没有 节约 ,反而浪 了),所以,不会位操作也没什 大不了的。
  不 ,不熟悉位操作的用 却都知道 “<<” “>>” 的另一用 事不能怪程序 ,几乎所有的 C++ 本都会从 “cin >> i;” “cout << i;” 入手。不用知道 两个操作符原来是干什 的,甚至不用知道 是怎 回事。 C++ 来到 个世界, 展了 C 言,使得 知其然不知道其所以然 的程序 也能好好工作。 许这 是它的一个 进步
 
 
标题: :可 的算 操作符
操作符是最容易理解的符号了,因 它与平 做的数学是完全相同的 规则 。就 小学的知 先乘除后加减 都完全适用。
  不 ,就像因 与生活的 逻辑 完全一 样导 致易于理解一般,与生活 逻辑 不一致的 问题 就比 较难 以理解了。比如 9 个苹果, 3 个小朋友分,平均 个小朋友可以分到几个苹果? 现实 中既不可能是 -9 个苹果,也不可能 -3 个小朋友分。而是 C/C++ 中的除法和求余却不得不面 对这种 情况。它 非但 于理解,而且 有不确定因素。
  引用:如果两个操作数都 正,除法和求模操作的 果也是正数(或零);如果两个操作数 都是 数,除法操作的 正数(或零),而求模操作的 则为负 数(或零);如果只有一个操作数是 数, 操作的 果取决于机器;求模 果的符号也取决于机器,而除法操作的 值则 数(或零)。
  笔 :以上 一大堆似乎有些 口舌。 这么说 吧,如果两个数同号, 一切都那 么简单 。即使是两个 数相除,只要把它 当成两个正数就可以了 —— 商肯定是正的,余数只要 对应调 整一下符号即可;如果是一正一 两个数相除,那 商肯定是 的,但是究竟是 多少可不一定,余数就更 难说 了, 是正是 都不能确定。
21 % 6 = 3;
21 % 7 = 0;
-21 % -8 = -5;
21 % -5 = ?;//
与机器相 ,可能是 1 可能是 -4
21 / 6 = 3;
21 / 3 = 3;
-21 / -28 = 2;
21 / -5 = ?;//
与机器相 ,可能是 -4 -5
  引用:当只有一个操作数 为负 ,求模操作 的符号可依据分子(被除数)或分母(除数)的符号而定。如果求模的 果随分子的符号, 除出来的 向零一 取整;如果求模与分母的符号匹配, 除出来的 取整。
   10 个苹果分 -3 个朋友,平均 个小朋友可以分到几个 剩下几个
 
 
标题: :操作符
第五章 始了,看得出来,从 章才真正 C++ 的基本内容。没有 里的内容,前四章都是狗屎。
  操作符就是我 理解的 运算符 了,不 C++ 算机 言,它与我 生活有着不一 逻辑 ,所以,在我 看来 简单 “3+4” ,到了 C++ 里,就得分成一个操作符和两个操作数了。
  操作符的含 以及它能得到的 果,不 仅仅 取决于操作符本身, 取决于操作数。当初学 C 言的 候, 发现 做除法要用 “10/3.0” 而不用 “10/3” 了一回。特 是从 BASIC 来的人, BASIC 里没有 这么强 型,所以 10/3 就是浮点数,要整除 得用 “Int()” 函数或改用 “/” 运算符(不是 VB 程序 都知道 个运算符的哦。)
  从 C/C++ 中弄明白了 “10/3.0” “10/3” ,反 来再去理解 C BASIC 的区 ,不 难发现 C/C++ 这样 做的确比 BASIC 高明得多。而 了解了硬件的运算机制后, 可以理解 这样 做不 仅仅 是高明,而且是必
  引用:有些符号既可以表示一元操作也可以表示二元操作。例如 *…… 这种 两用法相互独立 、各不相 ,如果将其 视为 两个不同的符号可能会更容易理解些。 …… 需要根据 符号所 的上下文来确定它代表一元操作 是二元操作。
  笔 是一个大家都明白,但是大家都不会去想的 问题 想起来,我 不去想,正是因 早已熟知。然而我 们读 程序可以上下 关联 算机要做到 点就不容易 —— 比如拼音 入法的自 动选词 。由此看来, C++ 编译 器是十分 秀的人工智能
 
 
标题: :多
引用: 格地 C++ 中没有多
  笔 :不只是 C++ 啦, C 中就是 这样 。不 ,正因 C++ 中没有多 ,而提供了 的数 ,所以 C/C++ 在数 使用上更灵活。
  多 的定 和使用没什 要多提的,用 就懂了。无非是多一 括号而已。不 ,如果把它跟指 一起用,倒是要注意的:二 对应 的是 指向指 的指 ,所以,如果要在函数 间传递 ,指 针类 型一定要正确:
   int a[3][4];
   int *p1 = &a[0][0];//a[][] 是一个 int 其取地址就是 int*
   int *p2 = a[0];//a[0] 然是 a 有一个元素,但它也是另一个数 的数
   int **p3 = a;//a 是一个二 的数
   int **p4 = &a[0];//a[0] 是一个数 名,它是 a 的一个成
  另外,有一个比 较难记 、容易混淆的用法:
   int (*p5)[4] = a;
   它容易混淆,是因 它与 “int *p5[4];” 有着截然不同的意 。前者是指定 一个指向数 的指 ,后者 是定 一个指 —— ing...
  本人在 实际 使用中, 常避 ,而用其它途径来使用一大堆数 。比如可以 这样 用:
   int a, b;// 的元素个数
   int *p = new int[a*b];
   for (int i=0; i      for (int j=0; j        p[i*a+j].....;
   delete []p;
  用 这种 方法,就是三 、四 也不用考 指向指 的指 这么复杂 西。 不是我不会,而是不高 去想
 
 
标题: 动态
,本 了个 开头 ,居然 new delete 了。我 偷窥 了一下:下一章 始才 到操作符,而且下章将有 专门 的一 节讲 new delete 。看来 里提到它 的目的只是 string 这样 类为 可以自 大小。
   new 的返回 是一个指 ,不 书暂时 没有提到 new 也会返回 NULL 的。是的, 暂时还 不用提内容不 够这么复杂 的情况。
  引用:在自由存 区中 建的数 组对 象数 是没有名字的,程序 只能通 其地址 接地 访问 堆中的 象。
  笔 里有两个 问题 ,一是 的名字 也是个指 ,指 当然也可以看成 的名字 本来就可以互 的,正如我前面 的一 “5[a]” 完全等价于 “*(5+a)” 。至于 a 是静 的数 动态 的指 ,没有区 。第二个 问题 里提到了 ,在没有 解内存之前, 这样说毕 竟理解上有 度。 是那句 有一定基 的人看的。
  令我耳目一新的是: new const —— 不是我不懂,而是 在没想到。再 了, 建一大堆 const 的内容,而且只能初始化 同一个 。那 有什 用?正如本 提到的一 这样 的数 组实际 上用 不大 。依我看,不是用 不大,而是根本没用。
   动态 应该 “delete []p;” 而不是 “delete p;” 是一个只要 住就可以的 问题 ,我之所以提上一句,是因 有人没有注意 过这 细节 ,包括很多自以 很了不起的程序
  引用:如果 漏了方括号 是一个 编译 器无法 发现 错误 ,将 致程序在运行
 
 
标题: C 格字符
给这 篇文章定下 标题: ,是因 为书 中就是 这样说 的。本 C++ 的,所以它推荐 者尽量使用 C++ 的内容,而 实际 上像我 这样 C 来的人, 习惯 于使用 C 格的字符串。 —— 我又想起了那句 原来我只是一个 古代 C++ 程序 ”( 《数 》一文 )
   C 言是用字符数 来做字符串的(当然 个字符数 必需要有一个 NULL 尾),因 字符串是如此常用, C 还专门开发 了一套 函数来 个特殊的数 。于是,我 们进 行字符串操作 ,可以忘 、忘 可以忘 char 个内置 型。
  正是因 如此,林 博士的《高 C++/C 程指南》中 别强调 ,不可以用指 赋值 和比 行字符串的 赋值 和比 个警告 于从 VB 转过 来的人尤其重要。
  使用 C 格的字符串有两点是必 的:一是要 给这 个数 组开 劈足 够长 度的空 ;二是一定不要忘了 NULL ;其中第二点一般程序 不会犯 ,因 为毕 竟没几个人用 “chat s[3] = {'a', 'b', '/0'}” 这种 方式来定 字符串。第一点就成了重中之重。我 strcpy 之前,有没有考 虑过 字符串可能的空 不足?
   “strn” 格的函数既救了大家也可能害了大家, 它救了大家,因 大家在 strncpy strncat 可以控制字符个数,即使源字符串太 ,也可以避免内存溢出。但是它存在的危 性是它不会 字符串添加 NULL
  所以, 写到 里再次做了一个提醒: 尽可能使用 库类 string”—— 我都忘了 是第几次提醒了,本 一而再再而三地提醒 者不要做 古代 C++ 程序
 
 
标题: :指 (三)指 与数
和数 是什 么关 系呢? 中曰 密切相 。其 ,那 真就是同一回事嘛。用到指 候,你未必会用到数 ;但是只要你用到数 ,你就必要然用到指 (即使你不知道)。
  正是因 可以用加或减运算来移 它所指的位置,而且 加一或减一正好移 到相 一个同 型的 量(不管 量占内存是多少),那 我有意将一堆同 型的 量放在一起,拿一个指 指向它 中的第一个,再 住它 的个数, 就成了数
  数 用一 方括号来解引用其中的某个成 也只是指 运算的 化。比如:
   int a[10];
   a[5] = 5;
  以上 这种 码谁 都用 都能理解。那 下面 行代 呢?
   5[a] = 5;
   这种 用法恐怕很少有人知道,即使 在知道了,恐怕也很 理解。 实际 上知道了数 运算的 实质 行代 的迷 就会立即消失: C/C++ 理括号的方法很 简单 ,将方括号前面的 和方括号内的 相加,得到一个新的指 ,再取指 所指的 “a[5]” 就完全等价于 “*(a+5)” “5[a]” 就完全等价于 “*(5+a)”
  那 “*(a+5)” 是什 运算呢?指 运算。因 编译 “int a[10];” 候,就等于定 了一个 “int * const a;” 将它初始化 指向 内存的某
   实际 上,正是因 “*(a+5)” 这种 用法 在太常用了, C 定了它的替代用法,后来 个替代用法被广 接受,而它的 实际 却被人 忘。
  以上内容本 未有提及, 是我看 看到 里的一点心得,作 为读书 写下来。不是 了炫耀。本 书虽 然是 有一定基 的人 的,但是 竟它只是按 就章地写下 C++ 规则 ,没有必要提及 技巧性高而又 用性少的内容。我之所以要写下来,目的是 了便于理解指 运算
 
 
标题: :指 (二)
的初始化与 赋值 :指 是一个 量,它可以被 赋值 ,也可以被求 。指 可以接受的 只有以下几
   1 编译时 可求 0 常量。(必 0 ,其 就是 NULL 啦)
   2 型匹配的 象的地址。(也就是用 & 运算符取一个 量的地址)
   3 、另一 象末的下一地址。( 这种 用法主要用在循 里,其 当指 值时 其所指的内存 行存取往往会 致灾
   4 、同 型的另一个有效指 (如 “p=q;” )。
  其中第 1 点,将 0 值赋给 ,主要是 了有一个状 表示 个指 空的 C/C++ 通常 0 NULL 然的确存在地址 0 的内存,但是 指望用指 访问这 个内存。
  初学者怎 才能消除 的恐惧?我 得首要的一点是清醒地 认识 并且 刻提醒自己 也是一个 。比如以下两行程序:
   int i;
   int *p = &i;
  看到 儿的人几乎无一例外把 p i 系起来( 当然不是坏事),但是,我 得更重要的是将 p i 分离,心里 住, p 是一个 量, 该变 量是有它的 的, i 的唯一 系是:目前 该值 正好等于 i 在内存中的位置。两 情况下 p i 将毫无 系:
   1 p 被改 ,如 “p = &j;” “p++;”
   2 i 量被 放,如离 i 的作用域。
 
 
标题: :指
C/C++ 的精 ,也是最 的部分。 —— 所有学 C/C++ 的人都明白 点,当年我初学的 候也是 这样 。但是, 在再回想指 ,我却很 它究竟 在哪儿。 应该说这 就叫 者不会,会者不 吧。 饱汉 不知 饿汉饥 是有一定的道理的,即使 饱汉 经饿过
  本 中矩地 解了指 的概念、定 与初始化、操作等。正如上面提到的 饱汉 不知 饿汉饥 ,我似乎很健忘,以至于不 得指 点在哪儿了。
  指 的灵活性可以把大量的工作化繁 易,前提是必 首很把足 繁的指 弄懂。听起来有点像 口令,事 就是 这样 ,你 在把 懂的 西弄懂了,日后可以把 事化 ,大事化小。
  从 VB 来的人一定会熟悉 值传递 地址 传递 两个概念, 实际 上, 地址 传递 这种说 法正是 了弥 VB 没有指 却有 似的需要才 明的。我 认为 C/C++ 程序 要想深入理解指 ,首先要抛弃 个概念。在 C/C++ 程序中,即使在函数 用中 传递 ,也不能 地址 传递 还应该说 值传递 ,只不 过这 传递 有点特殊,特殊在于借用 ,可以找到其 。就好像我 你一把 匙一 ,你通 过钥 匙可以 得更多,但是我 你的只不 匙。
  我前 子曾写 一篇 于指 的文章,之所以写那篇文章,是因 看到一大堆初学者在 论坛 上提 。通 过对 提的 问题 的分析,我 总结 了几点。下面,首先就先引用我自己写的《 于指 》中的片段吧(完整的文章 到我的个人主 页查 找):
  一、指 就是 量:
   然申明指 候也提 型,如:
   char *p1;
   int *p2;
   float *p3;
   double *p4;
   .....
  但是, 只表示 向某 型的数据,而不表示 型。 白了,指 都是一个 型:四字 无符号整数(将来的 64 位系 中可能有 化)。
  二、指 的加减运算很特殊:
   p++ p-- 的运算并不是 p 四字 无符号整数 加一或减一,而是 它指向下一个或上一个存 储单 元,它 实际 加减的 就是它所指 型的 size
  比如:
   char * 型指 次加减的改 量都是 1
   float * 型的指 次加减的改 量都是 4
   void * 型指 无法加减。
   要注意的是:指 不能相加,指 相减的差 int 型。
  正是因 有着不同于其它 量的运算方式,所以,在任何 候用到指 都必 明确 (即指 所指的 量的 型)。 就不 理解 函数声明 “int abc(char *p)” 用的 候却成了 “a = abc(p);” 这样 的形式了。
  三、用指 做参数 传递 的是指 针值 ,不是指 本身:
  要理解参数 传递 ,首先必 形参 弄明白。
  函数 A 用函数 B ,如果要 传递 一个参数 C 实际 是在函数 B 中重新建立一个 C ,并将函数 A 中的 C 值传 入其中,于是函数 B 就可以使用 了,在函数 B 中,无 有没有修改 C 于函数 A 中的 C 都没有影响。函数 B ,会将所有内存收回,局部 C 销毁 ,函数 B 对变 C 所做的一切修改都将被抛弃。
  以上示例中,函数 A 中的 C ,函数 B 中的 C 被称 形参 用函数 ,会在 B 函数体内建立一个形参, 形参的 参的 是相同的,但是形参的改 不影响 参,函数 ,形参被 销毁 参依然没有 化。
  指 也是一个 量,所以它也符合以上的 定,但是,指 存放的不 仅仅 是一个 ,而是一个内存地址。 B 函数 对这 个地址 行了改 ,改 的并不是形参, 而是形参所指的内存。由于形参的 参的 完全相同,所以, 参所指的内存也被修改。函数 个形参会被 销毁 ,指 化无法影响 参,但此前 它所指的内存的修改会持 有效。所以,把指 参数可以在被 函数( B )中改 函数( A )中的 量,好像形参影响了 参一
  注意:是 好像 。在 这过 程中,函数 B 影响的不是参数,而是内存。
  下面再来看 才的例子: “int abc(char *p)” “a = abc(p);” 中要用 * 号,因 函数必 知道 是指 么调 不加 * 号,因 为传递 的是 针值 ,而不是 所指内存的
  四、指向指 的指
  正因 也是一个 量,它一 要尊守形参与 参的 定。所以, 然指 做参数可以将函数内 对变 量的修改 到函数外,但是,函数体内 本身作任何修都将被 弃。如果要 本身被修改而且要影响函数外,那 ,被 函数就 应该 知道 所在的内存地址 这时 ,指 不再是指 ,而是 普通 。作 参数 传递 的不是 普通 ,而是指向 普通 的指 。即 指向指 的指
  如果 p 是一个指向指 的指 ,那 *p 就是一个指 ,我 妨就把它看成 q 。要 访问 q 所指的内存,只要 *q 就是了。用初中数学的 等量代 就知道, *q 就是 **p
  五、指
  之所以要把 独提出来,是因 本身就与指 有着千 系。即使你不想用指 ,只要你使用了数 实际 就在与指 打交道了。
  只要理解了指 本身就是 量,就不 理解 ,我 可以 且把它当成普通数 理, a[0] a[1] a[2]…… 就是数 的元素,只是, a[0] 是一个指 a[1] a[2] 也是一个指 。那 a 呢?当然也是指 ,但 是两 事。你可以 完全无 a 的存在,只去管 a[0] 等元素。 *a[0] *p 没有什 的区 。  
   有一个 西不得不提一下,它比 重要:
  指 的定 有两个可取的方式,它 各有 缺点: “int *p;” “int* p;” 是完全等价的,后者的好 人体会到 p 是一个 指向 int ,前者会 *p 是一个 int 量( 里没有定 int 量);但是前者的好 是不会 生混淆,如 “int *p, *q;” 人一眼就看出定 了两个指 ,而 “int* p,q;” 解成定 了两个指 实际 q 不是指
 
 
标题: :数
入本 第四章, 了。数 组难 不好 。但是数 非常重要 是肯定的,有 多基本的算法就是与数 一起出 —— 比如冒泡排序法。而离 了那些算法,数 本身也失去了价
  注意: 阅读 本章 概念加以小心,按平 的理解, 是多 中的概念,但是本 中的 指的是元素个数。 了避免干 ,我在 阅读 中用 个数 来取代
  引用:在出 现标 之前, C++ 程序大量使用数 保存一 组对 。而 代的 C++ 程序 更多地使用 vector 来取代数 ,数 格限制于程序内部使用,只有当性能 测试 表明使用 vector 无法达到必要的速度要求 ,才使用数
  笔 :我汗一个先!原来我只是一个 古代 C++ 程序
  数 的定 必需指明元素的个数,而且必 常量表达式 一点想必理解数 的人都会操作(即使弄 了, 编译 器也会立即 报错 ),但是真正去思考它的人也 不多。 里的 常量 概念是指程序在 编译阶 段就能求 的量。
  在 C 代,我 并不会 多地理会 常量 个概念,那是因 C 代没有 const ,而 define 西, 都知道它是在 编译 前就直接替 的。但是到了 C++ 代,由于 const 的存在,使 常量 个概念 得更普 了。
   const size1 = 5;// 是个 编译时 就可以求 的常量,它可以在数据的定 中使用。它的作用 仅仅 相当于 “define”
   const size = getsize();// 个常量是运行 才能求 的。
  除此之外, 常量求达式 的概念 指明 可是以一个算 式,只要 编译时 能求 。如 “char username[max_name_size + 1];” 这种 用法非 常常用,因 它可以避免在定 组时 忘掉 NULL
  数 的初始化可以 式指定,也可以不指定。 式指定 指定成 的个数可以小于等于 实际 个数,但不可以比 实际 个数大,如果小于, 其它元素 视为 未指定。 于未指定的元素的初始 ,它 遵循 量的初始化原 看《 量初始化》一文。
   大多数 本在介 字符串 都会提到,字符串其 是字符数 ,只是因 太常用,才会有 专门 的使用方法。本 也不例外。
  本 没有提数 实质 ,因 没有 者的眼睛。
  引用:数 著缺点在于:数 度是固定的, 而且程序 无法知道一个 定数 度。
  笔 :其 实这 正在程序 心中的一个痛。当我把数 参数 函数 ,函数 么处 西?要 大小有个事先的 —— 这样 的程序将失去很多通用性,要 么连 大小一起 传递给 人家
 
 
标题: C++ ,想 说爱 你不容
第三章就 这样结 束了,本章介 了三个 库类 型: string vector bitset
  可惜的是,整个第三章我都是草草 读过 的。一方面因 不属于 格意 上的 C++ 内容,另一方面 C 代的 西在不 抵触着它
  确切地 ,它 C 代的那些 西的替代品。它 存在的理由就是它 秀。然而 秀是一回事, 心又是一回事。
   C 言在 象方面的缺失,使 C 程序 更多地掌握了底 的操作。面 C++ 中的 string bitset 西, C 程序 员们 都知道,在 C++ 出来以前自己是怎 想方法 解决 过问题 的。刻苦才有刻骨 心, C++ 以后,是使用更 简单 安全的 是使用自己曾熟悉的老 法, 是一个取舍的 问题
  引用:程序 员应优 先使用 库类类 型。
  笔 :本 里放置了 这样 一个提示,大概是想告 这样 固派: 再死 腐旧套不放了,回 吧。 ,早在本 的前言就有了 似的内容。可是,我依然不能 自己静下心来 细读 并熟 第三章。
  也 有一天我会回 第三章,当然,也 不会。 string vector 这样 西,在 MFC 有更好的替代品
 
 
标题: bitset
当使用到布 尔变 量数 组时 是有点心疼。因 尔变 量只需要 0 1 种值 ,然而 编译 动辄 使用一个字 —— 甚至四个字 来存放一个布 尔变 量。面 1/32 的使用效率,叫人怎能不心疼?
  要想 节约 也不是没有 法,代价是写更多的代 :用 “&” 操作将 量的某一个 bit 取出来,一个字 就可以存放 8 个布 尔变 量。但是, 个代价是比 重的,重到足以 程序 望而生畏的地
   bitset 运而生,它可以方便地管理一系列的 bit 位而不用程序 自己来写代
  更重要的是, bitset 除了可以 访问 指定下 bit 位以外, 可以把它 一个整数来 行某些 统计 ,如:
   b.any();//b 中是否存在置 1 的二 制位?
   b.count();//b 中置 1 的二 制位的个数
   ……
  不 话说 回来,我 是不 习惯 bitset ,原因在于我是从 C C++ 的。 详细问题 留到后一篇文章中 讨论
 
 
标题: :迭代器:指 与数据 库杂 交的后代
迭代器与数据 的相似之 在于 end() 函数返回 值为 指向末元素的下一个 。跟数据 记录 集的 eof 这么 相似。 话说 回来,熟 C/C++ 的程序 一定不会忘了,利用下 标访问 组时 用的 是用 。就拿 “int a[10]; for(int i=0; i!=10; i++)” ,下 标为 10 就可以 视为 最后一个元素的下一个 。只是以前不会有 这么 的思考。
  迭代器与指 的相似之 在于它的 解引操作符 ,居然就是一个 “*” 号。而且存在着 “ivec[n]” “*ivec” 两个完全等价的操作。而且 持算 运算来移 访问 的元素。
  迭代的 const 用法与指 有个区
   “vector::const_iterator ivec = vec.begin();” ivec 并不是常量,只是它指向的元素会得到保 。如果要定 本身 const 的迭代器,要用 “const vector::ivec = vec.begin();”
  指 这样处 理的:
   const int *p = &i;//p 指向的 量是 const
   int* const p = &i;//p const
  地雷:任何改 vector 度的操作都会使已存在的迭代器失 。例如,在 push_back 之后,就不能再信 指向 vector 的迭代器的 了。
  笔 :我不得不相信所 的迭代器其本 就是一个指 了。因 vector 支持 动态 ,而且保 内存的 连续 。所以, 次改 它的 度都会 放已有内存、重新申 内存。 当然得失效
 
 
标题: for 句的条件思
for 句,我几乎 这样 写的: “for(int i=0; i 。但是,按本 法,我 这样 写似乎同 犯了两个 错误
   1 、本 中写 for 句中的第二个表达式(条件表达式) 时总 是用 != ,而不用 < 几天来 然心里 得奇怪,但是一直没去思考 里面的含 。本 没有急着告 所以然 ,只是提醒我 完本 的第二部分后就会明白。我等着吧 :)
   2 、我 得用 Max 这样 一个 量去代替某个需要用函数才 能返回的 可以增加运行效率,但是本 的建 与我的理解相反。它建 “i 数据 构可以 动态 …… 如果确 增加了新元素的 ,那 么测试 已保存的 size 环结 束条件就会有 问题 ,因 没有将新加入的元素 算在内。
  同 ,本 书为 了打消运行效率的 顾虑 提到了 函数 个概念。 没有到介 候,但是 C++ 是一个有机体,在 述某一个知 点的 候,不可能完全避免另一个知 点。 所以,我 是建 初学者不要急着 阅读
 
 
标题: vector
模板 了,可惜的是,在本 的第三章, 不能 让类 模板浮出水面,只能将就着提一下。
  引用:使用 模板可以 写一个 或函数定 ,而用于多个不同的数据 型。 ……vector 并不是一 数据 型,而只是一个 模板,可用来定 任意多 数据 型。
  笔 “vector ivec;” 中, “vector 是一个数据 型, C++ 支持 模板,以后大量接触 模板 个一定要 刻注意。
  引用:在元素 已知的情况下,最好是 动态 地增加元素。 …… 然可以 对给 定元素个数的 vector 先分配内存,但是更有效的方法是先初始化一个空的 vector 象,然后再 动态 地增加元素。
  将 vector string 比,可以 松地 empty() size() 函数和 [] = == != 等运算符。不 过这 似乎有个前提: C 言比 熟并且 VB String 型。因 string 然是一个 量,但是如果缺少 “char []” 的理解,将注定不能理解它。 —— 所以,我很反 某些人 可以不学 C 言直 接学 C++” 论调
 
 
标题: string
习惯 VC++ CString ,而此前用的又是 C 言,所以, 根没有看一眼 string 在既然 专门讲 它,我就看一看吧。
  定 与初始化:
   string s1;
   string s2(s1);
   string s3("value");
   string s4(n, 'c');// n c 成的一串
   string 象的 入除了可以 “cin >> s1;” 以外, 可以将 cin string 象一起作 getline() 函数的参数 “getline(cin, s1);” ,而且 个函数的返回 值还 cin
  除此之外, string 类还 empty() size() 等函数和 [] + = == 等运算符。
  地雷: empty() 函数的功能并不是将 象置空,而是 测试 是否 空。 可是与 CString Empty() 函数不一 的哦!
  本 书还详细 empty::size_type 型存在的原因。在使用 VC++.NET 候,我已 经见过 size_t ——strlen() 函数的返回 就是 size_t 象。当 我也没有 西,想来 应该 了支持 64 位机而 的吧。不 过现 在我知道了,原来我想得
  引用:通 过这 些配套 型, 库类 型的使用就能与机器无
   “+ 运算必 至少包含一个 string 可能 初学者摸不着 头脑 。比如 “s1 + s2” “s1 + "hello"” “"hello" + s1” 是合法的,唯独 “"hello" + "world"” 不合法。我在看懂 运算符重 之前也没有明白 个。本 由于 刚开头 ,离 运算符重 还远 呢,所以只告 诉读 、没有告 诉读 所以然 。我也不写了。
  引用:下 操作可作左
  笔 :人 一思考,上帝就 笑。 就是一个例 。下 操作可作左 有什 的?早就用 啊?比如 “char s[]="abcde"; s[2]='t';” 。可是 在的不是指 针变 量,而是 “string s("abcde");” “s[n]” 就不是 简单 操作一个内存了,而是从 “[] 函数中返回了一个 可以做左 ,并不是想当然的事
 
 
标题: :命名空 using 声明
实际 工作中 少用到 cin cout ,但是我 得要用它 必先 “using namespace std;” ,至于 么这样 做,三个字:不知道。
  本 从一 开头 就用到了 cin cout ,但是它没有 using ,而是 一次用到它 都写成 “std::cin” “std::cout” ,同 提醒 说这 两个字名是来自 std 命名空 的。于是,我似乎明白了 “using namespace std;” 的作用。
  也 C++ 在太 作者 迟迟 不介 更深入的内容,到了第一部分、第三章, 没有打算深入 using ,但又不得不 一点,于是提了 这样 两行:
using std::cin;
using std::cout;
  至此,究竟什 是命名空 ,命名空 是干什 的,我 是不懂。也 许书 后面会提吧
 
 
标题: 文件
文件的用 主要是代 重用 —— 重用不 仅仅 了减少工作量, 可以保 证每 一次重用都是完全相同的内容。
  正因 为头 文件可以多次重用,所以要防止有些只能出 一次的代 进头 文件中。比如 量的定 只能有一次,声明(含 extern 且不含初始化)却可以有多次。函数也是。
  引用:一些 const 象定 文件中。
  笔 :看到 里, 算想通了前面的困惑: const 常量的作用域 仅为 一个文件。正如我前面的估 const 常量是不 劈内存空 的,代 编译 候就被直接替 成常量 。而且, 编译 多个 CPP 是分 开编译 的。所以,它必 编译 候知道 常量的 。如果常量的作用域也是全局的,那 我告 诉编译 常量的 在另一个 CPP 将使其无可适从。
  避免 文件被重 包含是个比 有岐 法, 文件既然可以被多次包含, 又要避免重 包含? 是因 CPP 文件的 编译 。在 编译 任一个 CPP 文件 ,都要知道文件的内 容,所以,如果两个 CPP 都包含了同一个 文件,那 么头 文件就要被 编译 两次。但是同一个 CPP 如果重 复调 —— 甚至可能循 环调 —— 了某一个 文件, 要及 避免。 #ifndef...#define...#endif 可以起到 个作用。
   了,我一直没想通 VC++.NET “#pragma once” 是怎 工作的。它 不需要用 量来 标记 不同的 文件? 只需要一行也能 标记 出整个 文件的所有内容?
   第一部分、第二章
 
 
标题: class struct
首次考 class struct 系源自我 对类对 象占用内存数的 察。我 发现 VC++6 CString—— 这么强 大的 —— 它占内存居然是 4 sizeof(CString) 4 )。那 我就 认为 类对 仅仅 在内存中存放成 员变 量(《 C++ Primer 》称作 数据成 )而不存放成 函数。后来, 博士的《高 C/C++ 程指南》 ,才看到了比 法: C++ class struct 没有本 的区 —— 我将 话给 我朋友看 ,他 出不相信的神色。
   C++ Primer ,我已 熟知了 class struct 系。但是我 细细 地没有放 过书 中的任何一个字, 是作点 记录 吧:
  引用:用 class struct 关键 字定 义类 的唯一差 在于默 认访问级别 :默 情况下, struct 的成 员为 public ,而 class 的成 员为 private
  笔 :不 ,一般情况下公司与公司 间规 协议时 ,喜 写成 struct ,我想 可能是源于程序 C 承来的 习惯 有就是 协议 内容一般只包含数据,不包含函数,也 没有必要 定安全的 访问级别
  引用: 程新手 常会忘 记类 后面的分号, 是个很普通的 错误
  笔 中将 段文字 作一个地雷,我 是引用一下吧
 
 
标题: :枚
是我向来不太喜 用的 西,几乎我 见过 都是 这样 的:
   enum weekday {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
  我看到 里, 是想:多浪 啊,与其 这样 不如直接用 0-6 些数呢。以后要写 “weekday Today = Sunday;” ,哪有 “int Today = 0;” 舒服。
  本 似乎早看 透了我的心理,于是, 不从枚 入手,偏从 const 常量入手:
  引用:
   const int input = 0;
   const int output = 1;
   const int append = 2;
   这种 方法也能奏效,但是它有个明 的缺点:没有指出 是相 关联 的。 提供了一 替代方法,不但定 了整数常量集,而且 把它 聚集成
  笔 :大 就是大 ,他 能切中要害, 让读 者明白 准制定者的苦心。  
  另外,本 儿冷不丁地提了一个冷冰冰的概念:常量表达式。
  引用:常量表达式是 编译 器在 编译时 就能 够计 算出 果的整型表达式。整型字面 常量是常表达式, ……
  笔 我先汗一个。常量表达式必需是整数?我怎 不知道?那 “double pi = 3.14159;” 后面的字面 不属于常量表达式 是个疑 ,先 下来。
  引用:枚 举类 型的 象的初始化或 赋值 ,只能通 其枚 或同一枚 举类 型的其它 象来 行。
  笔 现实 生活中的 做人要 有点相似,呵呵。 简单 ,你 选择 了用名字来代替数 ,那就得始 如一地使用名字,不可以用数 或其它表达式。 比如 “weekday Today = Sunday;” 不可写成 “weekday Today = 0;” Sunday 就是 0
 
 
标题: typedef
期以来,我一直在疑惑: typedef 要它干什 ?因 没有它我照 可以完成所有任 。而有了它我反而 得无法适 。比如 “UINT i;” 不写作 “unsigned int i;” ?本 短的三句 我它存在的意
  引用: typedef 通常被用于以下三 目的: 藏特定 型的 实现 ,更 强调 使用 型的目的; 复杂 型定 ,使其更易理解;允 种类 型用于多个目的,同 使得 次使用 该类 型的目的明确。
   :第三 目的 我的启 特大。以后就 “typedef unsigned int age;” ,呵呵。
 
 
标题: :引用
引用是 C++ 的特色,一般用在函数的参数中。按有些 本的 法,叫 普通 量的用法,指 针变 量的效果 中本 没有 讲诉 引用在函数参数中的用法,只提了 给变 量起个 一个用 竟本 开头 )。 说实 在的,如果撇 函数参数, 真想不到引用有什
  引用 个概念本身也不 理解(除了 C 程序 有些不 习惯 以外),但是引用的符号却增加了理解它的 度,我 常在 论坛 上看到有初学者 “&” “*” 两个符号的疑惑,他 们问 问题 可以 非常基 ,但却表 出了 问题 以理解的特点:
   C 言中的指 经够复杂 的了,加再上一个引用,引用与指 有着千 系, 就算了,而且 用了 “&” 个符号。真 初学者忙昏了 。呵呵。下面四行程序,用到了两个 “&” 和两个 “*” ,但是它 的意 却全然不同:
int a;
int &b = a;//&
用在定 表示 量的性 质为 引用
int *c = &a;//*
用在定 表示 量的性 质为 & 用在表达式中表示取地址
int d = *c;//*
用天表达式中表示取指 针变 量所指的 量的
  写下以上文字,我 得有些越 了。 些内容估 在本 后面会 详谈 的,我心急了点
 
 
标题: const 常量的作用域 仅为 一个 CPP 文件
如果将 量定 放在任何 {} 的外面, 则该变 量是全局的, 规则 不适用于 const 常量。
  以前 然心里 隐隐约约 个感 ,但是从未正面考 虑过这 问题 。之所以 隐隐约约 有此感 ,是因 认为编译 器并不 const 常量 劈内存空
  我曾 经专门 过测试 :程序如下:
const int i = 5;
int *p;
p = (int *)&i;
cout << *p << "/t" << i << endl;
(*p)++;
cout << *p << "/t" << i << endl;
   测试结 发现 const 常量也是可以通 某些途径改 的,但是改 不起作用。我的解 是, 程器在生成机器 码时 将所有的 i 直接替 成了 5 。使得上面两个 cout 句都成了 “cout << *p << "/t" << 5 << endl;”
  回想起以前做 测试 ,便不 理解 “const 常量的作用域 仅仅为 它的 CPP 文件 ,因 为编译 器是 对每 CPP 文件 编译 的,只有在 才会 去理会 CPP 系。 然本 才看了个 开头 还说 将会在 2.9.1 看到 const 象局部于文件 。我不打算跳 式地 阅读 ,所以,我 是先保留我自己的理解吧。
   const 常量也 是可以成 全局常量的,方法是在定 候就加上 extern 。看到 里,我 于明白了《 extern 的困惑》中的困惑:原来,那 有些多余,而且增加了出 的可能性 的做法在常量的 理上派上了用
 
 
标题: 量的作用域
作用域 个概念是程序 都耳熟能 的知 点。 部分知 我几乎可以跳 ,不 阅读 了相 内容。 阅读过 程中 是有体会的:
  有无数 本曾 提醒 我:少用(尽量不用)全局 量,多用局部 量。其 ,即使是局部 量,也 有作用域大小的,局部 量的作用域也是越小越好。原因自然和少用全局 量一个道理。正如 中所言: 通常把一个 象定 放在它首次使用的地方是一个很好的 法。
  以往,我使用局部 是把它放在函数的 开头 ,表示 量在本函数中起作用。 唯一的例外是 for 句的循 环变 量( for (int i=0; i )。以后我就改改,把局部 量的作用域 小到 仅仅 用到它的
 
 
标题: extern 的困惑
extern 用来告 程序:你不用 我的 劈内存空 ,你只要知道 别处 声明 了。所以,我 是在程序包含多个 CPP 文件 这样 用:
   1 、在某一个 CPP 文件中直接定 义变 量,如 int i = 0;
   2 、其它 CPP 文件中声明 量,如 extern int i;
  但是, 中介 exturn 可以用来定 ,如: extern double pi = 3.1416; 特点是 extern 句包含 量的初始化。
  我 C++ 这样 做有些多余,而且增加了出 的可能性。因 “extern double pi = 3.1416;” 完全可以用 “double pi = 3.1416;” 来代替, 这样 做可以 与声明划清界 线 竟定 只能有一次,而声明可以无数次。如果没有 个特性,可以 程序 员简单记为 extern 的只能有一次, extern 的可以有无数次,而且 extern 不能指定初始 一特性的支持,使原本 简单 规则变 复杂 ,但没有 来灵活(众所周知 C++ 复杂 是以高度灵活 为补尝 的)。
   个段落 还让 认识 到了我以前使用 extern 的不足。我以往在同一个 CPP 文件中只使用一次 extern ,所以我往往是在文件 部用 extern 句来声明一下 量, 这样 然没有什 么错 ,但却会 致上下翻 :有 在文件的某一 用到 ,想看一下它的声明,不得不把 滚动 条拖到 上去 看。如果在用到它的段落 开头处 再声明,明 部声明要好一些
 
 
标题: 量初始化
int ival(1024);// 直接初始化
   int ival = 1024;// 制初始化
  以前的我常用第二 用法,原因很 简单 :从来没 见过 第一 用法。直到后来学 了林 博士的《高 C/C++ 程指南》。
  那本 讲类 的构造 时说 道: CMyClass b = a; 这种 形式看起来像 赋值 实际 用的是拷 构造函数。
  那本 书给 我的感 觉仅仅 停留在 类变 量的初始化中,一直没有 渡到内置 型。直到后来,我在用 VC++.NET 的向 功能 程序 ,才 发现 帮我 生了 似于 “int i(100);” 这种语 法来初始化。
  本 重点 强调 :初始化不是 赋值
  引用:当定 没有初始化的 ,系 候会帮我 初始化 量。 这时 ,系 提供什 么样 取决于 量的 型,也取决于 量定 的位置。 …… 内置 量是否初始化取决于 量定 的位置。在函数体外定 量都初始化 0 ,在函数体内定 的内置 量不 行自 初始化。 …… 类类 型)通 一个特殊的构造函数即默 构造函数来 实现 的。 个构造函数被称作默 构造函数,是因 它是 运行的。 …… 不管 量在哪里定 ,默 构造函数都会被使用。
  笔 :林 博士的《高 C/C++ 程指南》中 ,如果 没有定 无参数构造函数或拷 构造函数,系 会自 动产 两个构造函数,它 采用最 简单 值传递 位拷 来完成构造。
 
 
标题: 量和 量名
引用: 象是内存中具有 型的区域。
  笔 话说 得很直白,也只有 这样 面向 C++ 工的 才可以 这样说 竟初学者不知道内存与 量的 系,或者 没考 到。
  引用: C++ 保留了一些 用作各操作符的替代名。 些替代名用于支持某些不支持 C++ 操作符号集的字符集。它 也不能用作 标识 符(此 量名, )。
  一般的 只提到 C++ 量名不可以使用 关键 字,本 书还额 外提了 这样 一句,然后列出一个表,有 and bitand compl not_eq or_eq xor_eq and_eq bitor not or xor 。不 据我在 VC++.NET 测试 些是可以用作 标识 符的。
  都 说变 量名可以含 “_” 可以用 “_” 开头 ,但我一直没有 试过 光光用一个 “_” 来做 量名,正好 习题 里有,我就 了一下,果然可以的
 
 
标题: cout << (wchar_t )
C++ Primer 了,字符常量或字符串常量前加 L ,表示 wchat_t 型,于是我 了一下:
程序如下:
char a = "a";
wchar_t b = L"a";
cout << a << endl;
cout << b << endl;
果如下:
a
0012FEBC
,怎 现这 果?
我再
程序如下:
char a = 'a';
wchar_t b = L'a';
cout << a << endl;
cout << b << endl;
果如下:
a
97
由此可 cout << 运算符没有 wchat_t 的重 (或不健全)
 
 
 
标题: :内置 型之精度 选择
引用: …… 大多数通用机器都是使用和 long 型一 样长 32 位来表示 int 型。整型运算 ,用 32 位表示 int 型和用 64 位表示 long 型的机器会出 现应该选择 int long 型的 难题 。在 些机器上,用 long 算所付出的运行 代价 远远 高于用 int 行同 样计 算的代价。 …… 决定使用哪 浮点型就容易多了:使用 double 型基本上不会有 。在 float 型中 式的精度 失是不能忽 的,而 double 型精度代价相 float 型精度代价可以忽略。 上,有些机器上, double 型比 float 型的 算要快和多。 long double 型提供的精度通常没有必要,而且 需要承担 外的运行代价
 
 
标题: :内置 型之 int bool
第一部分,第二章
  引用: C++ 定了 个算 术类 型的最小存 ,但它并不阻止 编译 器使用更大的存 ,事 上, int 型,几乎所有的 编译 器使用的存 都比所要求的大。
  笔 :确 如此, VC++ int long 是一 大。 VC++.NET 增加了 _int64 的支持。
  引用:字符 型有两 char wchar_t wchar_t 型用于 展字符集,比如 字和日
  笔 :我怎 不知道 wchar_t ?我自己用包含 字的字符串 用的也是 char :(
  看到 bool 型,我心里 VC++ 有些气 。因 VC++ 里有一个 BOOL 宏。它的原型 “typedef int BOOL” 。既然 C++ 准已 bool 型, VC++ 加入 BOOL 的用意很明 :迎合更多的 习惯 。但是,即使非要增加 BOOL 的支持,我 认为 原型 应该这样 “typedef bool BOOL” 这样 更易于理解。
  当然了, 期以来我一直没有注意到 bool 也不 应该 但是正是 BOOL 的存在,阻碍了我 bool 的理解。
 
 
标题: :第一章:快速入
第一章:快速入
  本章的存在使本 书变 得不像一本 ,似乎成了 门书 可能是后来版本新加入的内容。以至于 一章 被排除在任何一个 部分 之外。
  本章 无厘 要介 cin cout 、注 while for if 等概念。 这么 西, 一个都介 点皮毛,然后 合成一个 例。
  我称其 无厘 有以下原因:如果本 不了解 C++ 者,那 么这 一章似乎是有用的,但是 C++ 的入 者使用本 书显 然很 ,我不了解国外的情况怎 ,至少我身 的人是 这样 ;如果本 了解 C++ 者,那 西都不用介 者也可以看懂那个 ,而且所 也没有存在的必要。
有一个小小的收
int main()
{
  return -1;
}
如果返回 值为 -1 Windows CMD 中运行也没有任何 外信息, Windows 并不 告运行失
 
标题: :《〈 C++ Primer 阅读 》前
之前,我已 一段 C++ 程序的 史,如果 C 言也算在内,可以追溯到十年前。用 BASIC 程序的 有十四年 (1992-2006)
   程序中所使用的参考 无非有两 :介 算法的 和介 绍语 法的 。我所 的参考 往往是同 两者的。而 对语 法的介 只是基于某一个 编译 器。
  于是, 十年来,我所学 “C/C++” ,从本 只是 Turbo C Visual C++ C/C++ 本身的理解也是被 编译 过滤 的内容。不是我不想去了解 C/C++ 的本 ,只是我 C/C++ 法典 有着与生 来的恐惧。
   个恐惧直到我 发现 了《 C++ Primer 中文版》,当我捧起 C++ ,我 于能理解 么每 有几十万人冒着被 死的危 前去朝圣。
   我用 来比 喻这 ,我知道 这样 并不合适,因 为绝 大多数中国人并不知道 的地位,但是我搜遍大 一个角落也找不到其它合适的比 源于中国人缺乏信仰。
  在半年前,我曾 经带 着无限的敬仰 阅读 了林 博士的《高 C/C++ 程指南》,并且及 / 修正了我的 习惯 。当然了,正如《 C++ Primer 》所言: C C++ 程序的正确格式存在着无休止的争 ……” 。所以,我所修正的只是 自由体 ,而不是与林 矛盾的方面。令我感到欣慰的是,《 C++ Primer 》居然也用一定的笔默来 格式与 格,不同的是,它同 种风 格,然后作出一个略 带倾 向性的建 。同 诫读 者: 一旦 选择 了某 种风 格,就要始 如一地使用。
  从 在起,我就要捧起 一本四五厘米厚、七百多 的圣 ,在 阅读过 程中, 免会有重点、要点要 记录 。我比 较爱书 ,不愿在 上做 标记 ,只好 选择 BLOG 这种 形式来做 读书
   以此作 我的 BLOG 明吧  

你可能感兴趣的:(收藏)