打印

C语言中的goto

[复制链接]
14219|59
手机看帖
扫描二维码
随时随地手机跟帖
来自 2楼
highgear| | 2010-11-9 00:39 | 只看该作者
DIJKSTRA 的 “GOTO 有害“:

  最近几年我观察到,程序员素质与他们编写的program中go to语句的使用频率成反比。最近,我又发现了使用go to语句会产生灾难性后果的原因;并且越来越确信在“高级”程序设计语言中(除了原始机器语言的所有程序设计语言),应该禁止使用go to语句。以前,我对这个发现没有足够重视;而最近的几次关于这个问题的讨论,使我认为自己有必要向公众阐述我的想法。

更重要的是,这些索引的值是不受程序员控制的;无论他们是否愿意,索引都会被生成(不是被程序员的program所明确写出,就是被process动态生成)。他们提供了描述process进程的独立坐标系。

那么,为什么我们需要这样的独立坐标系呢?原因是——并且看上去更像是连续process的固有属性——我们只能通过process的过程来解释一个变量的值。如果我们需要计算一个房间中的人数,比如说n,初始值为0;那么我们必须在每一次看见有人进入房间时增加n。在中间的某个时候,如果我们看见一个人进入房间却没有增加n,那么n的值将比屋内实际的人数少1!

滥用go to语句会立刻使得在process过程中寻找有意义的、描述该process的坐标系变得异常困难。通常,人们也很重视那些经过精心选择的变量的值,但是毫无疑问,这是因为这些与该过程相关的变量是可以被理解的。使用go to语句,人们当然还可以从program一开始就唯一的计算一组动作来描述这个过程(即:一种规格化的时钟)。困难的是,这样的坐标系,尽管唯一,但是却完全没有用处。在这样一个坐标系中,定义过程中的这些点变得异常困难,比如说,证明n等于房间中人数减1!

go to语句看上去太原始了;并且很容易使得program变得混乱。我们可以乐观的考虑使用从句来抑制go to语句的使用。我并不认为上面提及的从句可以满足任何需求,但是无论如何,从句可以使程序设计者,以一种有益的并且是可操作的方式,建立独立的坐标系来描述process。

很难以一种公正的角度来结束本文。我是不是因为受某人的影响而变得太武断了?很明显,我受到了Peter Landin和Christopher Stracher的影响。最后,我想应该写下(对此我印象很深刻)Heinz Zemanek在1959年年初于Copenhagen召开的pre-ALGOL会议上的一段话。话中明确地表示:他怀疑,在任务语句和语法层面上,go to语句能否与其它语句一样被同等对待。谦虚地说,我应该责备自己没有重视他的论述。

不使用go to语句的论点不是什么新观点。我记得曾经读过一篇明确说明应该限制go to语句的建议性**,但是现在无法找到它的出处了;推算起来,它可能是C. A. R. Hoare写的。[1, Sec. 3.2.1]中,在建议使用case construction方面,Wirth和Hoare一起得出了结论:“类似条件从句,case construction比起go to语句和switches更能清晰的描述program的动态结构,并且可以大量减少program中标签的使用。”

首先我想说的是,尽管程序设计者的工作在他构建完正确的program时就结束了,但是(不可否认)控制其program走向的process也是他工作中重要的一部分;这是因为正是在这个process中,期望的效果得以完成、动态的行为得以令人满意的按照计划实行。并且一旦program写好以后,就该由机器替代执行相应的process了。

其次我想说的是,人类的思维很适宜掌控静态联系,而形象化的能力却相对较弱。正是由于这个原因,我们应该(就像优秀的程序员了解自身的局限性一样)尽可能缩短静态program与动态process之间的概念差异;尽可能使program(在文本上展开)与process(在空间上展开)的相关性尽量密切。

现在来考虑如何描述一个process的过程。(您可以用一种很具体的方式来思考这个问题:假设process是一段时间内的一串连续动作,并且它在一个任意动作之后结束,那么使用什么样的数据能够使我们在同一点上重新执行这个process呢?)如果我们说,program文本是一串纯粹的任务语句(为了讨论,仅考虑它是单一动作),那么我们绝对可以找到一个点,这个点处在两个连续动作描述之间。(如果没有go to语句,我保证上个句子中的最后三个单词(连续动作描述)会有歧义:如果我们断句为“连续的动作描述”,其意思是连续的文本空间;如果断句为“连续动作的描述”,其意思时连续的时间。)我们不妨将这些在文本中恰当位置出现的点称作一个“文本索引textual index”。

当我们引入条件从句(if B then A)、二选一的选择从句(if B then A1 else A2)、由C. A. R. Hoare发明的多选一的选择从句(case[i] of (A1, A2, …, An)),或者由J. McCarthy发明的条件表达式(B1 → E1, B2 → E2, …, Bn → En)以后,process的过程中必存在一个文本索引。

在语言中引入procedure以后,我们必须承认一个单独的文本索引不再有效。由于文本索引指向procedure体内部,其动态过程只有当我们引用这个procedure时,才会被刻画。在procedure内部,我们可以通过文本索引序列刻画这个process的过程。序列的长度等价于procedure被动态调用的深度。

现在我们考虑循环从句(比如while B repeat A或者repeat A until B)。逻辑上讲,这样的从句是多余的,因为我们可以用递归的procedures来描述循环。但是由于现实如此,所以我也不想排除循环从句:一方面,循环从句可以通过现在的有穷设备很方便的实现;另一方面,被称作“归纳”的推理模式可以使我们的思维仅仅抓住由循环从句产生的过程。在循环从句的内部,文本索引对于描述process的动态过程不再有效。然而,在循环从句的每一次进入时,我们可以联合使用一种叫做“动态索引”的机制,客观地计算当前相应循环的循环次数。因为循环从句可以嵌套使用(就像procedure被调用一样),我们会发现,现在的process过程可以被文本或者动态的混合序列独一无二的描述。

使用特权

评论回复
板凳
cubasa| | 2010-7-15 10:10 | 只看该作者
大部分人都说,出轨尽量要少出。
你突然发现,出轨有时候想起来也是很美妙。

GOTO相当于是出轨,会破坏程序的和谐性,除非你有十足的把握不出事情。

使用特权

评论回复
地板
寄语信鸽| | 2010-7-15 10:18 | 只看该作者
大部分人都说,回帖尽量要少回。
你突然发现,回帖有时候想起来也是很美妙。

使用特权

评论回复
5
Apmvista| | 2010-7-15 11:18 | 只看该作者
大部分人都说,围观楼主。
你突然发现,同情一下楼主有时候想起来也是很美妙的。

使用特权

评论回复
6
宇容创行| | 2010-7-15 11:30 | 只看该作者
对goto的最大容忍
一个函数内只允许提供一个标号,供goto使用,通常只用在出错处理上

使用特权

评论回复
7
阿尔帕西诺| | 2010-11-4 18:10 | 只看该作者
风险问题……

使用特权

评论回复
8
handlike| | 2010-11-4 20:06 | 只看该作者
goto out;
........
........
.......
out:_nop_();

使用特权

评论回复
9
程序匠人| | 2010-11-4 20:09 | 只看该作者
理论上来说,凡是用goto能实现的功能,不用goto也能做到。
所以。。。。。

使用特权

评论回复
10
zq1987731| | 2010-11-4 20:14 | 只看该作者
goto用来处理错误信息到是不错,Linux的Kernel中就是这么干的

使用特权

评论回复
11
handlike| | 2010-11-4 20:17 | 只看该作者
理论上来说,凡是能用方程可以做的,不用方程也可以做到(列算式)。
所以。。。。。

使用特权

评论回复
12
520810| | 2010-11-4 20:30 | 只看该作者
以身犯险啊

使用特权

评论回复
13
beyondbit| | 2010-11-4 20:43 | 只看该作者
呵呵  理论上是这样的

使用特权

评论回复
14
Etual| | 2010-11-5 08:40 | 只看该作者
通常只用在错误处理上面。

使用特权

评论回复
15
ayb_ice| | 2010-11-5 08:41 | 只看该作者
不可滥用
想想
如果发现某个人的工程中大量使用goto,你会怎样

使用特权

评论回复
16
大道至简| | 2010-11-5 08:43 | 只看该作者
goto 我几乎都不用的。
上次用goto是半年前,一年只用2次最多。

使用特权

评论回复
17
zhiyonghe| | 2010-11-5 09:09 | 只看该作者
别滥用
但该用时绝不手软

使用特权

评论回复
18
老鱼探戈| | 2010-11-5 12:41 | 只看该作者
尽量少用,
不过编译后goto也就是一条jmp语句

使用特权

评论回复
19
程序匠人| | 2010-11-5 20:51 | 只看该作者
结构化编程没有给goto留位置。

使用特权

评论回复
20
223178825| | 2010-11-5 21:37 | 只看该作者
学习了

使用特权

评论回复
21
chenwy1986| | 2010-11-5 22:49 | 只看该作者
希望像LZ说的那样很美妙,本次发布的产品中俺就用了,心里一直嘀咕着,但是,话说回来,汇编里不大量用jmp吗?都不会出现问题。要是有问题,我想goto语句就不会写入教材了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

868

帖子

2

粉丝