第Ⅰ部分 程 序
—— 常见C++ Bug大围剿 ——
第1章 入 门
首先,让我们将目光转向ENIAC Mark I刚出现的时代。某一天,操作员碰巧注意到ENIAC计算机不能正常运行,于是他就寻找引发问题的原因,结果发现原来是一只蛾子飞进了机器,且死在继电器触点(relay
contact)上,从而导致机器出现了问题。
于是,这个操作员就取出蛾子并将它贴在自己的工作日志本中,然后添上注释:这是在系统中找到的bug。这样,第一个计算机bug就诞生了。
注:
虽然人们都相信这是单词bug在计算机领域的第一次使用,但是对于其他行业并不是如此。术语bug在此之前早已出现,用于描述各种机械故障。
当然,计算机bug引入到笔者的知识体系中,还是很久以后的事情。在笔者12岁时,就编写了自己的第一个程序。该程序是一条长长的汇编语言指令,用于计算2加2的和,但是其结果却是2。这个程序仅仅是一条长指令,却有一个bug。
本章包含几个“第一”:笔者第一次苦熬到凌晨2点才找到第一个bug(程序3);笔者负责的第一个C程序设计测试中的第一个问题(程序2);还有大部分编程类图书中的第一个程序——
Hello World。
花絮
在ATM出现之前,您必须去银行通过人工进行储蓄业务。通常,您要使用支票簿(checkbook)中预打印的存款单(deposit
slip),这些存款单都带有您的账号,其中账号被写在存款单底部的磁条(magnetic ink)上。
如果您用完了所有的存款单,银行会为您提供新的存款单。新存款单上没有写入账号,因此在使用银行的自动机器处理它时,机器会不予处理,只能由银行工作人员手动输入您的账号才能办理业务。
这就给骗子以可乘之机。他们私下印制“通用”存款单,这些非法存款单与正规的“通用”存款单非常相似,惟一的不同就是它们的底部磁条上已经写入了骗子的账号。
然后骗子走进银行,将自己印制的存款单塞进银行保存通用存款单的箱子中。
骗子的骗术是这样的:当客户走进银行进行存款时,就可能会拿到一张假的存款单。客户填写存款单上的相关内容,并将钱存到银行。但是,由于存款单已经包含了一个账号,计算机就会自动处理这个存款单,并将钱存到已经写入到该存款单底部磁条上的账号上。银行工作人员手动为存款单输入的账号将被忽略。也就是说,这个客户的钱存到了骗子的账号上,骗子正在窃取钱财。
负责该案子的侦探很为难,因为存款丢失了,却没有人知道原因。最后他将自己的侦察范围缩小到银行存款业务上,并决定亲自尝试,多次将钱存到银行,看看有何异常发生。由于这位侦探使用的是自己的钱,所以存款的金额非常少,实际上每次只存6分。
这位侦探花费一个星期的时间进行多笔存款。每次他走进银行都是填存款单、排队,然后将6分钱存入银行;接着再填款单、排队、存入6分钱……;这样一直进行到银行下班。银行的工作人员认为他有点神经病。终于有一天,侦探的一笔存款丢失了。于是,他要求银行提供存款记录,看看那天还有谁存过6分钱。确实有一个人存入了6分钱,很显然,这个人就是骗子,他被捕了。
1.1 程序1:Hello World
在大部分编程类图书中,Hello World程序几乎都是第一个示例程序,而且没有什么差别。但是,这里的Hello World程序是一个有错误的程序。
在编写像Hello World这样简单的程序中,您会犯错误吗?请先看看下面这个Hello World程序,然后再回答:
1 /************************************************
2 * The "standard" hello world program. *
3 ************************************************/
4 #include <iostream>
5
6 void main(void)
7 {
8 std::cout << "Hello world!\n";
9 }
(请参见“提示228”和“答案6”)
花絮
下面是一段与计算机故障有关的对话:
用户:今天我无法登录网络系统,我的“调制解调节器”不能正常连接。
工作人员:看看您的“调制解调节器”,告诉我是哪个灯在闪烁。
用户:我不能。
工作人员:如果您不能向我描述实际情况,我就无法帮助您解决问题。难道您就不能看看您的“调制解调节器”并告诉我它的状况吗?
用户:是的,不能。
工作人员:为什么?
用户:我的“调制解调节器”在地下室里。
工作人员:那您为什么不去地下室看看?
用户:您在跟我开玩笑吧?这儿的地下室有6英尺深的水!
工作人员:噢,我知道问题所在了。计算机不能在水中工作。
用户(很吃惊):真的吗?
|