查看完整版本: 新手發問C語言Goto指令
頁: [1] 2 3

a91337a 發表於 2017-3-30 09:44 AM

新手發問C語言Goto指令

為何網路上說不能常用GOTO指令,我用了好幾次並沒有對程式判斷或著任何問題{:36:}<div></div>

weirdococo 發表於 2017-3-30 11:29 AM

不是不能用,是因為那會破壞某一些觀念上的編程典範,想像一下,一般來說,一個subroutine有兩3個進入點,有兩個是goto過來的,那宣告進入時夾帶的參數就不見得會被傳入,subroutine的參數就變成只能當參考用的東西!

johnwanz 發表於 2017-3-30 09:24 PM

GOTO是合乎規範的語法, 自然是有用的.

不過, 對於結構化程序來說, 不熟悉使用場合, 就很容易使程序呈現出不結構化的形式. 加上, 不用GOTO也能寫出很不錯的程序, 所以, 教學上, 通常都不建議使用GOTO, 或要求避免使用GOTO.

例如, 在我公司, 會要求工程師不要用; 如果有覺得需要, 必須先徵詢過主管意見. (絕大多數都是程序結構不良, 才會希望用GOTO.)

ps. 在特定條件下, GOTO其實也是很好的一種表達方式, 只是要注意使用時機....<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

a91337a 發表於 2017-3-31 11:30 AM

johnwanz 發表於 2017-3-30 09:24 PM static/image/common/back.gif
GOTO是合乎規範的語法, 自然是有用的.

不過, 對於結構化程序來說, 不熟悉使用場合, 就很容易使程序呈現出 ...

經過大大的見解我已經充分了解到GOTO的意義存在^^謝謝給我這個新手解答

a91337a 發表於 2017-3-31 11:33 AM

weirdococo 發表於 2017-3-30 11:29 AM static/image/common/back.gif
不是不能用,是因為那會破壞某一些觀念上的編程典範,想像一下,一般來說,一個subroutine有兩3個進入點, ...

看來GOTO語法也有限制性,謝謝大大給我這個新手具有參考性價值見解^^<br><br><br><br><br><div></div>

seraphnew 發表於 2017-3-31 11:01 PM

Function 中的Return 某種程度上也是一種goto。
通常建議不用,是因為邏輯判斷關係。

CoNsTaRwU 發表於 2017-4-4 01:43 AM

本帖最後由 CoNsTaRwU 於 2017-4-4 01:49 AM 編輯

不知道原 Po 有學過 category theory 相關的東西嗎?
如果有學過那就很好懂了

越抽象的東西包含的資訊越少,但是越通用,也越有用
越具體的東西包含了越多的資訊,然而越不通用,也越...沒用 XD
(越通用的意思是需求越少,越有用的意思是能夠在越多情況下派上用場)

我們先來討論最極端的兩種狀況:
1. 一個系統裡所有東西都是最抽象的:
這根本沒意義,因為這樣代表這整個系統裡的所有東西都是一樣的,你寫的每一行程式在語意上都是同一個意思,你的程式到底在做什麼要等到把整個程式看完之後讓看你程式的人自己去猜...
這怎麼想都不是一個有用的點子吧...

2. 一個系統裡所有東西都是最具體的:
這也一樣很沒意義,因為這樣的程式可讀性一樣很糟糕
因為不管是寫程式的人或是閱讀程式的人都必須要記憶很多很多(事實上是無限種)的表達式是什麼意思
就算兩行程式做的事情只有一點點不一樣,用的語法就完全不同...
這不管怎麼想也都不是一個好點子... XDD

如果你整個程式的流程控制全部都用 goto 去實現,那就會是第一種最極端的狀況
所有的敘述都沒有額外的資訊提供給讀者,通通都是 goto...
當然,goto 最通用,因為所有流程控制能作到的事都能夠用 goto 土砲出來
然而應該不會有人這麼做 (直接去寫組語是不是比較快)

那第二種極端狀況是什麼情況?
想像你只不過是一個迴圈迭代的次數更改了,語法就完全不同了
而光是迴圈就有無限種,因為連迭代次數不同都要換一種迴圈來用
寫這種程式一定會崩潰吧...
而且寫得下去應該也可以算是天才了吧
總之,就是一個完全無法做抽象的情況

那到底該怎麼取捨抽象和具體的程度呢?
先講答案,答案是「在不損失資訊的前提下盡量做到最抽象」

整個 category theory 幾乎都圍繞在這種議題上 (當然不只這些議題啦...)
而且 category theory 可以說是理論計算機科學裡相當基礎&重要的科目
如果原 Po 有興趣建的話,建議可以去找 Conceptual Mathematics 這本書來讀讀 (如果原 Po 沒學過的話啦)
這本書用非常易懂的方式講解 categories,真的非常值得一讀...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

o_g349 發表於 2017-9-13 12:05 PM

本帖最後由 o_g349 於 2017-9-13 12:07 PM 編輯

johnwanz 發表於 2017-3-30 09:24 PM static/image/common/back.gif
GOTO是合乎規範的語法, 自然是有用的.

不過, 對於結構化程序來說, 不熟悉使用場合, 就很容易使程序呈現出 ...
補充一下特定條件下甚麼時候會使用到,最常見的例子就是 malloc 和 free,以下列這段程式來說:int func(void) {  /* 回傳是否成功,若回傳 1,代表失敗,0 代表成功 */
  void * one;
  void * two;
  void * three;
  one = malloc(1);
  if (one == NULL) /* 如果要求不到第一個變數所需的記憶體 */
    return 1; /* 只好直接回傳錯誤,1 代表失敗 */
  two = malloc(1);
  if (two == NULL) { /* 如果要求不到第二個變數所需的記憶體 */
    free(one); /* 只好先釋放掉第一個變數的記憶體 */
    return 1; /* 再回傳錯誤,1 代表失敗 */
  }
  three = malloc(1);
  if (three == NULL) { /* 如果要求不到第三個變數所需的記憶體 */
    free(two); /* 只好先釋放掉第二個變數的記憶體 */
    free(one); /* 再釋放掉第一個變數的記憶體 */
    return 1; /* 最後回傳錯誤,1 代表失敗 */
  }
  /* ... 做一些事 ... */
  free(three); /* 釋放掉第三~一個變數所需的記憶體 */
  free(two);
  free(one);
  return 0; /* 回傳成功,0 代表成功 */
}可以改寫成int func(void) {
  int error = 1; /* 一開始先設定為發生錯誤,1 代表錯誤 */
  void * one;
  void * two;
  void * three;
  one = malloc(1);
  if (one == NULL) /* 如果要求不到第一個變數所需的記憶體 */
    goto exit; /* 跳到 exit,error 會保持為 1,代表發生錯誤 */
  two = malloc(1);
  if (two == NULL) /* 如果要求不到第二個變數所需的記憶體 */
    goto free_one; /* 跳到 free_one,error 會保持為 1,代表發生錯誤 */
  three = malloc(1);
  if (three == NULL) /* 如果要求不到第三個變數所需的記憶體 */
    goto free_two; /* 跳到 free_two,error 會保持為 1,代表發生錯誤 */
  /* ... 做一些事 ... */
  error = 0;
  free(three); /* 釋放掉第三~一個變數所需的記憶體 */
free_tow:
  free(two);
free_one:
  free(one);
exit:
  return error; /* 回傳是否成功,若回傳 1,代表失敗,0 代表成功 */
}這樣就不會因為要 malloc 的變數變多導致程式碼以等差級數遞增使得程式變得複雜,而是有幾個變數程式碼就有幾行,goto 使得程式碼變得更好維護、更不會出錯...<div class='locked'><em>瀏覽完整內容,請先 <a href='member.php?mod=register'>註冊</a> 或 <a href='javascript:;' onclick="lsSubmit()">登入會員</a></em></div>

lijinf2 發表於 2018-1-9 10:26 PM

goto是老語法,破壞程序的可讀性和模塊化,已經被新的標準拋棄,建議寫程序不要用goto,goto能表達的意思其他語句都能表達

HaKkaz 發表於 2018-1-26 02:40 AM

另外,也會降低程式的可讀性,程式若很長,別人看時還要邊找goto到哪,很累<br><br><br><br><br><div></div>

70413456 發表於 2018-1-29 06:03 PM

因為Goto是沒有規則可言的,例如在循環裡面設置了Goto,沒有設置循環結束判斷,就很容易陷入死循環。

allenbody 發表於 2018-2-4 09:09 PM

goto 在小程式看起來應該是沒問題 但對於大型project的source code來說 會造成很多maintain的問題
優點大概就是programmer 可以偷懶吧 缺點debug到天荒地老

神之風想 發表於 2018-5-5 09:30 AM

謝謝大大的分享喔,小弟覺得很好喔~解決了我的問題

kuolung1 發表於 2018-6-8 08:23 PM

基本上,我是不用 goto 的,我寫30年程式,但也不是完全沒用,看個人習慣

jackyo04 發表於 2018-6-20 04:16 PM

我都用簡單的迴圈表達耶,用GOTO要拉來拉去很麻煩,自己用就還好,如果程式量大的話,光交接或整合就會增加別人的工作量,所以要用前先想一下吧<br><br><br><br><br><div></div>
頁: [1] 2 3