複製鏈接
請複製以下鏈接發送給好友

goto語句

鎖定
goto語句也稱為無條件轉移語句,其一般格式如:
goto 語句標號
其中語句標號是按標識符規定書寫的符號, 放在某一語句行的前面,標號後加半角冒號“:”。語句標號起標識語句的作用,與 goto 語句配合使用。
中文名
無條件轉移
外文名
goto
領    域
網路
作    用
編寫程序

goto語句語句舉例

goto語句也稱為無條件轉移語句,其一般格式如下:
goto 語句標號;
其中語句標號是按標識符規定書寫的符號,放在某一語句行的前面,標號後加半角冒號“:”。語句標號起標識語句的作用,與goto句配合使用。如:
label: i++;
loop: while(x<7);
goto loop;
C語言不限制程序中使用標號的次數,但各標號不得重名。goto 語句的語義是改變程序流向, 轉去執行語句標號所標識的語句。
goto 語句通常與條件語句配合使用。可用來實現條件轉移, 構成循環,跳出循環體等功能。
但是,在結構化程序設計中一般不主張使用 goto 語句, 以免造成程序流程的混亂,使理解和調試程序都產生困難。

goto語句C# 語言

using System;
using static System.Console;
class Program
{
    public static Int32 Main(String[]args){ 
            int n = 0; 
            WriteLine("input a string :\n"); 
            judge: if (Read()!= '\r') { 
                n++; 
                goto judge; 
            } 
            WriteLine("{0}", n); 
            return 0; 
        } 
}

goto語句C語言

統計從鍵盤輸入一行字符的個數。
#include<stdio.h>
int n=0;
int main(void) {
    printf("input a string: ");
        judge: if (getchar()!='\n') {
        n++;
        goto judge;
    }
  printf("output: %d\n",n);
}
例如輸入:abcdefghijklmnopqrstuvwxyz
然後回車Enter
輸出:26
本例用if語句和goto語句構成循環結構。當輸入字符不為'\n'時即執行n++進行計數。
然後轉移至if語句循環執行,直至輸入字符為'\n'才停止循環。

goto語句彙編語言

goto語句與彙編語言裏面的jmp指令相同,(無條件轉移
1+2+3........+8+9+10
NASM描述:
mov ax,1
mov bx,0
start:add bx,ax
inc ax
cmp ax,11;比較指令
jzend ;零轉移
jmp start
end:
;
;start: end:是標號

goto語句Pascal

格式 goto <標號>;
其中標號需要申請,在程序開頭寫label <標號1>,<標號2>,……;
其中,標號必須為四位以內的正整數
在該段落內還需要有<標號>:語句 表示將要轉向的方向。

goto語句delphi

//Goto語句用在跳轉行號, 可以跳轉到當前結構層內任意位置.
//必須在聲明處用label關鍵字聲明行號.
//由於Goto語句會破壞程序的結構, 不推薦使用.
var
a,b: Integer;
label
X,Y;
begin
if a > b then
goto X
else
goto Y;
X:
WriteLn('a > b');
Y:
WriteLn('b > a');
end;

goto語句批處理

使用冒號標記
:start
goto start

goto語句按鍵精靈

使用rem做標記,可以用中文
rem 開始
goto 開始

goto語句VBA

使用冒號做標記,但是跟批處理的不一樣,冒號在後面
start:
goto start

goto語句發展歷程

問題起源
20世紀60年代中期以後,計算機硬件技術日益進步,計算的存貯容量、運算速度和可靠性明顯提高,生產硬件的成本不斷降低。計算機價格的下跌為它的廣泛應用創造了極好的條件。在這種形勢下,迫切要求計算機軟件也能與之相適應。因而,一些開發大型軟件系統的要求提了出來。然而軟件技術的進步一直未能滿足形勢發展的需要,在大型軟件的開發過程中出現了複雜程度高、研製週期長、正確性難以保證的三大難題。遇到的問題找不到解決辦法,致使問題堆積起來,形成了人們難以控制的局面,出現了所謂的“軟件危機”。為了克服這一危機,一方面需要對程序設計方法、程序的正確性和軟件的可靠性等問題進行系列的研究;另一方面,也需要對軟件的編制、測試、維護和管理的方法進行研究,從而產生了程序設計方法學
goto語句是有害的觀點
1968年,Edsger Wybe Dijkstra首先提出“goto 語句是有害的”論點,向傳統程序設計方法提出了挑戰,從而引起了人們對程序設計方法討論的普遍重視。
goto語句的爭論
在20世紀60年代末和70年代初,關於 goto 語句的用法的爭論比較激烈。主張從高級程序語言中去掉 goto 語句的人認為,goto 語句是對程序結構影響最大的一種有害的語句,他們的主要理由是: goto 語句使程序的靜態結構和動態結構不一致,從而使程序難以理解,難以查錯。去掉 goto 語句後,可直接從程序結構上反映程序運行的過程。這樣,不僅使程序結構清晰,便於理解,便於查錯,而且也有利於程序的正確性證明
反對意見的人認為, goto 語句使用起來比較靈活,而且有些情形能提高程序的效率。若完全刪去 goto 語句,有些情形反而會使程序過於複雜,增加一些不必要的計算量。
關於goto語句的解決方法
1974年,高德納對於 goto 語句爭論作了全面公正的評述,其基本觀點是:不加限制地使用 goto 語句,特別是使用往回跳的 goto 語句,會使程序結構難於理解,在這種情形,應儘量避免使用 goto 語句。但在另外一些情況下,為了提高程序的效率,同時又不至於破壞程序的良好結構,有控制地使用一些 goto 語句也是必要的。用他的話來説就是:“在有些情形,我主張刪掉 goto 語句;在另外一些情形,則主張引進 goto 語句。”從此,使這場長達10年之久的爭論得以平息。
後來,Corrado Böhm及Giuseppe Jacopini從理論上證明了:任何程序都可以用順序、分支和重複結構表示出來。這個結論表明,從高級程序語言中去掉 goto 語句並不影響高級程序語言的編程能力,而且編寫的程序的結構更加清晰。
goto語句的結果
C/C++等高級編程語言中保留了 goto 語句,但被建議不用或少用。在一些更新的高級編程語言,如Java不提供goto語句,它雖然指定goto作為關鍵字,但不支持它的使用,使程序簡潔易讀;儘管如此後來的c#還是支持 goto 語句的, goto 語句一個好處就是可以保證程序存在唯一的出口,避免了過於龐大的 if嵌套。
可以考慮使用goto的情形
1.從多重循環中直接跳出
很多人建議廢除C++/C的goto語句,以絕後患。但實事求是地説,錯誤是程序員自己造成的,不是 goto 的過錯。goto 語句至少有一處可顯神通,它能從多重循環體中一下子跳到外面,用不着寫很多次的break語句。例如:
for(......){
for(....){
for(.....){
// 如何衝出重重包圍?
}
}
}
break; 只能跳出單層的循環,return 將整個函數都返回了,沒法再繼續了,顯然也不行,所以我們想到了 goto 。如果是在陷入了很深層次的循環裏想要跳出最外層的循環,用 goto 直接跳出卻比用 break 一個循環一個循環地跳出要好得多。有人甚至形象比喻説:“就像樓房着火了,來不及從樓梯一級一級往下走,可從窗口跳出火坑。” 其實,你可以將 break 和 continue 理解成弱化了的 goto 語句。
2. 出錯時清除資源
如果一個函數有多個出口,則在每個出口處,會產生巨大的退出代碼,如下例一,每個函數只能有一個出口,所有的資源釋放必須放在出口統一解決,那全部使用大括號,十幾個,幾十個 if 判斷條件下來,大括號深得數不清。這種代碼可讀性不好,一旦寫錯了,難於尋找錯誤。所有這些問題,一個 goto 就解決了。
當程序要分配和清除資源時(像內存、或處理字形、窗口、打印機),這種情形下用 goto 通常是為了複製代碼或清除資源。若遇到這種情況,程序員就要掂量是 goto 的缺點更討厭,還是複製代碼那令人頭痛的維護更討厭,最後還是認為 goto 的缺點更可忍受。
例子一:不用 goto ,想想需要申請的指針是10個的話,程序怎麼寫?
void Func(void)
{
char* p1=null;
char* p2=null;
char* p3=null;
p1=(char*)malloc(10);
if(!p1) return;
p2=(char*)malloc(10);
if(!p2)
{
free(p1);
p1=null;
return;
}
p3=(char*)malloc(10);
if(!p3)
{
free(p1);
p1=null;
free(p2);
p2=null;
return;
}
…… //指針使用過程
if(p1)
{
free(p1);
p1=null;
}
if(p2)
{
free(p2);
p2=null;
}
if(p3)
{
free(p3);
p3=null;
}
}
例子二:用 goto
void Func(void)
{
char* p1=null;
char* p2=null;
char* p3=null;
p1=(char*)malloc(10);
if(!p1) goto Func_End_Process;
p2=(char*)malloc(10);
if(!p2) goto Func_End_Process;
p3=(char*)malloc(10);
if(!p3) goto Func_End_Process;
… //指針使用過程
Func_End_Process:
if(p1)
{
free(p1);
p1=null;
}
if(p2)
{
free(p2);
p2=null;
}
if(p3)
{
free(p3);
p3=null;
}
}
3.可增加程序的清晰度的情況。
若不使用goto語句會使功能模糊,有時候使用 goto 語句,一眼就看清楚了程序的意圖,可用那些對應的循環break語句等實現的語句段,要想老半天才搞清楚程序意圖的情況,也可考慮使用 goto 語句。
不加限制地使用 goto 帶來的弊端
1.很明顯,不加限制地使用goto破壞了清晰的程序結構,使程序的可讀性變差,甚至成為不可維護的"麪條代碼"。例如下例:
A: //code section A
//code
goto B;
//code
goto C;
B: //code section B
//code
goto A;
//code
goto C;
C: //code section C
//code
//goto B;
//code
goto A;
這樣好像已經能夠説明問題了,隨着標籤的增多,帶來的混亂局面是很難扭轉的,對調試、走讀、理解代碼都會造成很大的障礙,如果寫這樣的代碼,那代碼維護絕對會是一場噩夢。
2.不加限制地使用goto經常帶來錯誤或隱患。它可能跳過了某些對象的構造、變量的初始化、重要的計算等語句,例如:
goto state;
String s1, s2; // 被goto 跳過
int sum = 0; // 被goto 跳過
……
……
state:
……
如果編譯器不能發覺此類錯誤,每用一次 goto 語句都可能留下隱患。
goto語句問題的提出直接推動了結構化程序設計(structured programming)的思想和程序設計方法學的誕生和發展。結構化程序設計方法引入了工程思想和結構化思想,使大型軟件的開發和編程都得到了極大的改善。
結構化程序設計方法的主要原則可以概括為自頂向下,逐步求精,模塊化,限制使用goto語句。
  1. 自頂向下:程序設計時,應先考慮總體,後考慮細節;先考慮全局目標,後考慮局部目標。不要一開始就過多追求眾多的細節,先從最上層總目標開始設計,逐步使問題具體化。
  2. 逐步求精:對複雜問題,應設計一些子目標作為過渡,逐步細化。
  3. 模塊化:一個複雜問題,肯定是由若干稍簡單的問題構成。模塊化是把程序要解決的總目標分解為子目標,再進一步分解為具體的小目標,把每一個小目標稱為一個模塊。
  4. 限制使用 goto 語句
結構化程序設計方法的起源來自對 goto 語句的認識和爭論。肯定的結論是,在塊和進程的非正常出口處往往需要用 goto 語句,使用 goto 語句會使程序執行效率較高;在合成程序目標時,goto 語句往往是有用的,如返回語句用goto。否定的結論是,goto 語句是有害的,是造成程序混亂的禍根,程序的質量與 goto 語句的數量呈反比,應該在所有高級程序設計語言中取消 goto 語句。取消 goto 語句後,程序易於理解、易於排錯、容易維護,容易進行正確性證明。作為爭論的結論,1974年高德納發表了令人信服的總結,並證實了:
  1. goto 語句確實有害,應當儘量避免;
  2. 完全避免使用 goto 語句也並非是個明智的方法,有些地方使用 goto 語句,會使程序流程更清楚、效率更高。
  3. 爭論的焦點不應該放在是否取消 goto 語句上,而應該放在用什麼樣的程序結構上。其中最關鍵的是,應在以提高程序清晰性為目標的結構化方法中限制使用 goto 語句
關於 goto 使用語句的一些建議
goto 語句在結構化編程技術出來後,被當作破壞結構化程序的典型代表,可以説,在結構化程序設計年代,goto 語句就像洪水猛獸一樣,程序員都唯恐避之不及;可後來在微軟的一些例子程序中經常把 goto 語句用來處理出錯,當出錯時,goto 到函數要退出的一個label那裏進行資源釋放等操作。goto 語句也不是隻可以用於出錯處理,其它地方都不可以用了。下列關於使用 goto 語句的原則可以供讀者參考。
  1. 使用 goto 語句只能 goto 到同一函數內,而不能從一個函數里goto到另外一個函數里。
  2. 使用 goto 語句在同一函數內進行 goto 時,goto 的起點應是函數內一段小功能的結束處,goto 的目的label處應是函數內另外一段小功能的開始處。
  3. 應該避免向兩個方向跳轉。這樣最容易導致"麪條代碼"。