goto在c语言中的作用,关键字goto在C语言中的使用
1、goto關鍵字基礎知識關鍵字goto從字面的意思就是"去哪里"的意思,專業一點的話表示無條件跳轉的意思(有學過匯編的小伙伴應該會覺得非常像jump指令),在C語言中的使用格式是:goto label,表示跳轉到label的位置,并且我們的label一般都寫在語句的開頭,寫成label:的形式。(下面一個小例子來簡單介紹用法)
intmain(intargc,char*argv[]){
//無條件跳轉到標簽處
gotothelastBug;
printf("未知bug\n");
//標簽定義
thelastBug:
printf("最后一個bug\n");
return0;
}
注意點:
1)goto label;后面的分號一定得打。(個人經常忘記,這里提醒一下各位)
2)goto只能在函數內部無條件跳轉,不能從一個函數跳轉到另外一個函數。
3)label:的標識在使用goto語句的前后均可,不遵循先定義后使用。
4)label的作用域在函數內部,不同函數之間可以定義相同的label。
(上面的幾點注意項大家有時間可以在電腦上實驗下)
2、備受爭議的C語言關鍵字-goto
對于goto的使用程序語言界算是爭議不斷,并且大部分大學C語言老師在講到到goto這關鍵字的時候一般都會叫大家慎用goto關鍵字,甚至有部分老師一棍子拍死“禁止使用goto關鍵字”。個人覺得一棍子打死終究不合適,慎用比較說得過去點。如果說禁止使用那為什么還要在C語言標準中定義呢?干脆直接剔除算了。有句話說得好,"存在即合理"。
我們在高中學習算法的時候應該畫過基本的結構圖,三大基本的程序結構分別是:順序結構、分支結構和重復結構,這個三種結構就能夠創造出所有的邏輯結構,那么我們C語言就是順序執行的表示順序結構;if、switch等表示分支結構;while、for等結構表示的是重復結構。可以說我們不用goto語句也能編寫出我們想要實現的程序。
那么我們換一種思考方式,我們的重復結構就比如說三個循環語句for、while、do...while,在我的實踐編程經驗來看他們都可拆成:一個分支語句+goto語句,下面我舉一個if+goto實現for語句的例子供大家參考:
/**********************************
* Fucion: main
* Descri: if+goto 模擬for語句
**********************************/
intmain(intargc,char*argv[]){
//循環變量定義
inti=0;
i=0;
Loop:if(i>5){gotoLoopEnd;}i++;
//for(i= 0;i<5;i++)
//{
printf("%d\n",i);
gotoLoop;
//}
LoopEnd:
printf("最后一個bug\n");
return0;
}
其他的重復語句也可以由分支+goto模擬,這里就不再書寫代碼了,只是說用模擬循環的方式似乎書寫上不是很美觀。所以我覺得并不是goto不好用,而是怕大家濫用,導致對程序的把控力的下降。
那么我們再深入一點看待goto語句,我上面說了該關鍵字非常的靈活,其實goto本身的功能是非常簡單的,就是一個跳轉到所定義的標簽label位置,靈活的地方在于label可以在一個函數內部每一句的開頭都可以定義。
所以我們要控制goto為我們所用主要就是控制label的使用問題,后面我們會有例子教大家怎么控制label,所以goto語句還是一個非常有潛力的關鍵字,對于設計巧妙高效的算法會非常有用!所以個人覺得只要對goto語句的使用加以管束為我們開發服務,這未嘗不是一件好事。
3、大佬都是這么用goto的!
1)瞄一瞄linux中的goto
我們讀過linux相關代碼的小伙伴會發現goto語句的使用無處不在,首先我截取了uboot1.1.6中的一部分代碼來欣賞一下(畢竟uboot也是大佬寫的):
?????????_20200624095511.png (36.16 KB, 下載次數: 0)
2020-6-24 09:55 上傳
?????????_20200624095515.png (29.15 KB, 下載次數: 1)
2020-6-24 09:55 上傳
第一張是一個函數的前半部分,第二張為該函數末尾,中間代碼還有非常多這樣的語句。程序大體的意思是:打開一個文件,然后對該文件一系列操作,一旦操作不成功就會goto到error標簽,然后關掉該文件,否則如果都執行成功了就會return 1.表示成功。
沒錯,這是goto常用的一種用法就是處理多種異常情況,這樣帶來的好處是高效,為什么這么說呢?有些小伙伴就就會問題了,我直接在每個錯誤處理用return返回一個變量,然后再函數外面通過判斷這個標志進行故障處理不就好了嗎?
個人覺得如果你有這樣的想法是好的,不過在我們進行驅動編程的過程中還是要有一定的規范,如上面的代碼我們在函數前面申請了mem_fb,既然沒有使用成功我們就應該在該函數中直接釋放它,這樣能夠對函數有更好的封裝和隱秘性。那有些小伙伴又會說,分支語句每個分支里面進行處理就好了呀,這種處理方式會使得每個分支語句里面都有相同的釋放處理語句,加大了程序。
2)使用goto跳出多層循環
我們都知道break僅僅只能跳出當前循環,如果遇到多層循環需要跳出的問題,就需要每個循環都需要break一下,并且還需要內層循環傳遞相關信號讓外層循環break掉,從而退出多層循環,這樣做實在有點麻煩,而且代碼結構也不好看,那么有些小伙伴就會問那我直接return掉就好了,我們來看一下下面的代碼你就會有自己的決定了:
/**********************************
* Fucion: main
* Descri: goto跳出多層循環
**********************************/
intmain(intargc,char*argv[]){
inti=0,j=0,k=0;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
//if(條件不滿足)
//goto ERROR;
}
//if(條件不滿足)
//goto ERROR;
}
//if(條件不滿足)
//goto ERROR;
}
return1;
ERROR:
//相關資源釋放
printf("最后一個bug\n");
return0;
}
/**********************************
* Fucion: main
* Descri: return跳出多層循環
**********************************/
intmain(intargc,char*argv[]){
inti=0,j=0,k=0;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
//if(條件不滿足)
//相關資源釋放
//return 0;
}
//if(條件不滿足)
//相關資源釋放
//return 0;
}
//if(條件不滿足)
//相關資源釋放
//return 0;
}
printf("最后一個bug\n");
return1;
}
3)作者對goto關鍵字小結
這里僅僅代碼個人的使用觀點:
(1)上面兩個例子中我們使用goto是可以借鑒的,對程序的效率和美觀有一定的效果;
(2)對于一般的程序goto語句的功能盡量簡單,便于分析和代碼的整潔,如果不能帶來較大的優勢還是盡量少用;
(3)個人平時研究控制理論,對于任何事物覺得要么是發散、要么是收斂比較好分析處理問題,對于震蕩問題相對比較麻煩,所以對于如下圖2種goto的使用情景我是推薦的,前面說了只要我們控制好goto的靈活度就能夠為我們服務,那么我們只需要規定在一個函數中其只是單向跳轉,我們對程序的把控能力就大大提高了。
?????????_20200624095519.png (52.15 KB, 下載次數: 2)
2020-6-24 09:55 上傳
4、總結
好了,今天的內容就到這里吧,看完這個文章希望大家能夠有點收獲吧,也希望大家能幫忙傳播傳播
總結
以上是生活随笔為你收集整理的goto在c语言中的作用,关键字goto在C语言中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux cpu占用100原因查询,如
- 下一篇: 更改c语言程序保存地址吗,C语言文本文件