打印

C语言中的goto

[复制链接]
楼主: 呆板书生
手机看帖
扫描二维码
随时随地手机跟帖
21
救火车| | 2010-11-6 10:22 | 只看该作者 回帖奖励 |倒序浏览
同意楼上几位观点,错误处理时用goto很美妙。
任何书本上的东西都不是绝对的。
充分理解为什么不推荐用之后,才会理解什么时候可以用。

使用特权

评论回复
22
handlike| | 2010-11-6 10:58 | 只看该作者
用过的人说美妙,没用过的人一本正经地喊谨慎。
这就叫“谁用谁知道”。
掌握了goto 语句的使用要点,使用上没有问题。

使用特权

评论回复
23
呆板书生|  楼主 | 2010-11-6 11:02 | 只看该作者
美妙和谨慎,完全没有矛盾,

我们做菜的时候,下点盐巴就很美妙,但要谨慎地下

使用特权

评论回复
24
ji_dan| | 2010-11-8 21:41 | 只看该作者
我也用过一次,好像没有出现什么差错~

使用特权

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


那天匆忙,没有详细说,今天再补充一下。
在结构化编程中,只有3种程序结构:
1、顺序结构
2、条件分支结构(包括多重分支结构)
3、循环结构(当型、直到型)

这3种结构,都不需要依赖goto语句即可实现。所以说:“结构化编程没有给goto留位置。”

在实际应用中,goto仍旧有被用到。一般都是为了程序的效率。

这个话题的关键,就是要有结构化的编程理念。
有了这个理念,偶然用用goto,只要不出格,也是可以的。

使用特权

评论回复
26
highgear| | 2010-11-8 22:58 | 只看该作者
对于 mcu 这样的小程序, 用了 goto 也不会体现出多少的危害, 基本上也很少有第三方去审查代码, 所以用了就用了, 没有什么大不了。 如果以后程序规模越来越大, 需要仔细规划程序结构, 认真避免潜在的危险时, 自然会考虑 goto 的弊端。

当然了, 从小项目开始做起, 养成良好的习惯, 就更好了。

审查别人的代码时, 最痛恨的代码之一就是 goto. 因为需要付出额外的精力, 因为首先 goto 打断了思维顺序, goto 可以跳到函数内的任何地方, 你得来回检查; 其次, goto 可能跳过一些相关语句而带来潜在的危险。

使用特权

评论回复
27
mohanwei| | 2010-11-8 23:48 | 只看该作者
指针乱飞很危险,你能不用指针么
数组越界很危险,你能不用数组么
switch-case漏掉几个也很危险,你能不用么
……

在出错处理上,goto就是最佳的结构化手段,其他的都是浮云。
当然,如果普通的顺序结构你也要用goto去搞一搞,然后说goto很可恶,最好不用……那设计goto的人只能无语了

使用特权

评论回复
28
highgear| | 2010-11-9 00:17 | 只看该作者
一些高级语言如java, C#可以完全不用指针(C#必须标记为 unsafe, 才能使用指针), 而且数组越界会抛出 exception. 而 c 中无法避免使用指针, 这也是很多严重的 bug 产生的源泉以及被告诫要提高警惕(例如很多面试考题要考察 ASSERT)原因。而 goto 除了直接从多重循环中跳出外, 其他方面并没有多少优势而且可以很好地被替代。
  我们无法避免不犯错误, 但我们有办法可以减少出错的几率, 特别是一些大型的 c/c++ 项目, 宏观上总体的安全比微观上的一些小技巧或是一些小便利更为重要。

使用特权

评论回复
29
highgear| | 2010-11-9 00:27 | 只看该作者
http://zh.wikipedia.org/zh-cn/Goto

对于goto使用的批评
GOTO语句一直是批评和争论的目标,主要的负面影响是使用GOTO语句使程序的可读性变差,甚至成为不可维护的"面条代码"。随着结构化编程在二十世纪六十年代到七十年代变得越来越流行,许多计算机科学家得出结论,即程序应当总是使用被称为'结构化'控制流的命令,如循环以及if-then-else语句来替代GOTO。甚至在今天,许多程序风格编码标准禁止使用GOTO语句。为GOTO语句辩护的人认为,加以限制地使用GOTO语句不会导致低质量的代码,并且声称在许多编程语言中,一些任务如果不使用一条或多条GOTO语句是无法被直接实现的。如有限状态自动机的实现、跳出嵌套循环以及异常处理。

大概最著名的对于GOTO的批评是艾兹格·迪杰斯特拉在1968年的一封叫做Go To Statement Considered Harmful的信。[2]在那封信中,迪杰斯特拉认为不加限制地使用GOTO语句应当从高级语言中废止,因为它使分析和验证程序正确性(特别是涉及循环)的任务变得复杂。另外一种观点出现在高德纳的Structured Programming with go to Statements [3]中,**分析了许多常见编程任务,然后发现其中的一些使用GOTO将得到最理想的结构。

这些批评在一些编程语言的设计上起到了效果。虽然Ada语言的设计者在二十世纪七十年代晚期意识到了对于GOTO的批评,这条语句仍旧被包含进去,主要是用来支持自动生成那些goto语句必不可少的代码。[4]但是,作为goto语句目的地的标签必须使用双尖括号括起来(如:<<Start_Again>>),而这个语法在其他语言中都不被使用。这使得检查程序中goto目的地的存在变得容易。goto语句本身使用简单的形式goto Start_Again;.

[编辑] 变体
有许多不同的语言构成可以看作是goto的变形:

[编辑] 限制的GOTO
许多语言,如C语言和Java,提供了相关的控制流语句,如break和continue,它们都是有效地被限制的goto语句。它们的作用是无条件跳转,但是只能够跳到循环块结束的位置——继续进入下一循环(continue)或者结束循环(break)。

[编辑] switch/case结构
C语言、C++和Java中的switch语句高效地实现了一个多路goto,跳转目标有表达式的值来选择。

使用特权

评论回复
30
程序匠人| | 2010-11-9 00:30 | 只看该作者
俺家楼下小区花坛里,原本没有路,走的人多了,便也成了路。
为什么呢?因为走大路比较费工夫,于是很多人为了“抄近路”而直接穿越了花坛的草丛,踩出一条新路来。
俺有时也会随大流,但俺心里知道抄近路是不合规则的,难免要踩坏花花草草。
goto有点类似于“抄近路”。——有效率,但不合规则。

使用特权

评论回复
31
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过程可以被文本或者动态的混合序列独一无二的描述。

使用特权

评论回复
32
highgear| | 2010-11-9 00:49 | 只看该作者
程序员素质与他们编写的program中go to语句的使用频率成反比, 呵呵。

使用特权

评论回复
33
hyhv126| | 2010-11-9 08:45 | 只看该作者
goto很傻很天真,本来衬衫革履的,因为想要凉快,穿上拖鞋,凉快是凉快,但不协调

使用特权

评论回复
34
coldra| | 2010-11-9 08:59 | 只看该作者
有些需要安全认证的地方,无论有什么道理,只要有用goto,直接打回来。

使用特权

评论回复
35
sszxxm| | 2010-11-9 09:02 | 只看该作者
砒霜有毒,人人知道,潘金莲当年就是用砒霜把武大郎毒死的。
但是现代医学用砒霜治疗晚期肝癌。
砒霜有错吗?
goto有错吗?
都没错!

用对了地方就是好,用错了,是人的问题,不是goto或砒霜的问题。凡事别钻牛角尖,该出手时就出手,这没错,没到出手的时候,就该哪儿凉快哪儿呆着去!

使用特权

评论回复
36
wjh1215| | 2012-6-25 22:47 | 只看该作者
在开发系统程序中,因为代码量大,运行的都是和WINDOES的许多函数挂勾的东西,当然要限制的使用GOTO,而在嵌入式中就不同了,况且goto还可用在汇编语言中,而单片机的C代码本身就是不是高级的C,是属于介于汇编和C之间的语言,当然要更巧妙的多用goto了,在嵌入式中用GOTO,就如同在C语言中夹着汇编代码了,#program asm ...了,只当把goto当作汇编代码,直接实现跳转

使用特权

评论回复
37
dong_abc| | 2012-6-26 02:21 | 只看该作者
顶 goto ;

使用特权

评论回复
38
wukunshan| | 2012-6-26 08:35 | 只看该作者
goto语句是否好用,由你的C编程水平确定。“尽量少用”是针对C语言初学者。goto语句和if语句等都是C语言里的基本语句,没有好坏的说法。

使用特权

评论回复
39
zhaofy521| | 2012-6-26 09:08 | 只看该作者
话说,我天天在goto

使用特权

评论回复
40
渤海三叠浪| | 2012-6-26 10:09 | 只看该作者
本帖最后由 渤海三叠浪 于 2012-6-26 10:28 编辑

9# zq1987731


呵呵  linux这么弄 我们就有必要这么弄么?



饲养员敢摸老虎屁股,你也敢摸??


linux 用估计也是在核里面,就是有固定的需求。
如果我做的100个项目都用相同的程序  我也敢用。敢用也不用。哼

呵呵 不过zq1987731的水平可超过饲养员了。至于普通游客还是算了吧。老老实实,做有把握的事情就好

使用特权

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

本版积分规则