goto關鍵字你不知道的"那些事"(C語言提升)

2021-02-19 最後一個bug

    今天在前面放了一段伍佰的歌曲《last Dance》,這首老歌最近突然火了是因為一部愛情穿越電視劇《想見你》,劇情還不錯大家感興趣可以看一看,大夥不要天天搞研究,敲代碼,多一點不一樣的生活會有不一樣的精彩,效率也會大大提高。

    好了,之前一直都沒有透露自己的聯繫方式,最近一些小夥伴私信給我說,有問題在公眾號私信我比較麻煩而且有時候也沒注意訂閱號,希望我能夠提供個人微信。確實最近發現私信的給我的圖片有時候打不開,為了更好的交流這裡公布一下個人的微信號,大家可以添加一下,研究、學習、生活上都可以跟我交流,我也可以準備酒,等待著你的故事:

    好了,要進入今天的主題了,今天我們要討論的是C語言中相對比較冷門的知識關鍵字goto!

    關鍵字goto從字面的意思就是"去哪裡"的意思,專業一點的話表示無條件跳轉的意思(有學過彙編的小夥伴應該會覺得非常像jump指令),在C語言中的使用格式是:goto label,表示跳轉到label的位置,並且我們的label一般都寫在語句的開頭,寫成label:的形式。(下面一個小例子來簡單介紹用法)

int main(int argc, char *argv[]) {

//無條件跳轉到標籤處

goto thelastBug;

printf("未知bug\n");

//標籤定義

thelastBug:

printf("最後一個bug\n");

return 0;

}

    1)goto label;後面的分號一定得打。(個人經常忘記,這裡提醒一下各位)

    2)goto只能在函數內部無條件跳轉,不能從一個函數跳轉到另外一個函數。

    3)label:的標識在使用goto語句的前後均可,不遵循先定義後使用。

    4)label的作用域在函數內部,不同函數之間可以定義相同的label。

    (上面的幾點注意項大家有時間可以在電腦上實驗下)

    對於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語句

**********************************/

int main(int argc, char *argv[]) {

//循環變量定義

int i = 0;

i = 0;

Loop:if(i > 5){goto LoopEnd;}i++;

//for(i= 0;i<5;i++)

//{

printf("%d\n",i);

goto Loop;

//}

LoopEnd:

printf("最後一個bug\n");

return 0;

}

    其他的重複語句也可以由分支+goto模擬,這裡就不再書寫代碼了,只是說用模擬循環的方式似乎書寫上不是很美觀。所以我覺得並不是goto不好用,而是怕大家濫用,導致對程序的把控力的下降。    那麼我們再深入一點看待goto語句,我上面說了該關鍵字非常的靈活,其實goto本身的功能是非常簡單的,就是一個跳轉到所定義的標籤label位置,靈活的地方在於label可以在一個函數內部每一句的開頭都可以定義。所以我們要控制goto為我們所用主要就是控制label的使用問題,後面我們會有例子教大家怎麼控制label,所以goto語句還是一個非常有潛力的關鍵字,對於設計巧妙高效的算法會非常有用!所以個人覺得只要對goto語句的使用加以管束為我們開發服務,這未嘗不是一件好事。

    我們讀過linux相關代碼的小夥伴會發現goto語句的使用無處不在,首先我截取了uboot1.1.6中的一部分代碼來欣賞一下(畢竟uboot也是大佬寫的):

    第一張是一個函數的前半部分,第二張為該函數末尾,中間代碼還有非常多這樣的語句。程序大體的意思是:打開一個文件,然後對該文件一系列操作,一旦操作不成功就會goto到error標籤,然後關掉該文件,否則如果都執行成功了就會return 1.表示成功。
    沒錯,這是goto常用的一種用法就是處理多種異常情況,這樣帶來的好處是高效,為什麼這麼說呢?有些小夥伴就就會問題了,我直接在每個錯誤處理用return返回一個變量,然後再函數外面通過判斷這個標誌進行故障處理不就好了嗎?
    個人覺得如果你有這樣的想法是好的,不過在我們進行驅動編程的過程中還是要有一定的規範,如上面的代碼我們在函數前面申請了mem_fb,既然沒有使用成功我們就應該在該函數中直接釋放它,這樣能夠對函數有更好的封裝和隱秘性。那有些小夥伴又會說,分支語句每個分支裡面進行處理就好了呀,這種處理方式會使得每個分支語句裡面都有相同的釋放處理語句,加大了程序。

    我們都知道break僅僅只能跳出當前循環,如果遇到多層循環需要跳出的問題,就需要每個循環都需要break一下,並且還需要內層循環傳遞相關信號讓外層循環break掉,從而退出多層循環,這樣做實在有點麻煩,而且代碼結構也不好看,那麼有些小夥伴就會問那我直接return掉就好了,我們來看一下下面的代碼你就會有自己的決定了:

/**********************************

* Fucion: main

* Descri: goto跳出多層循環

**********************************/

int main(int argc, char *argv[]) {

int i = 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;

}

return 1;

ERROR:

//相關資源釋放

printf("最後一個bug\n");

return 0;

}

/**********************************

* Fucion: main

* Descri: return跳出多層循環

**********************************/

int main(int argc, char *argv[]) {

int i = 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");

return 1;

}

    這裡僅僅代碼個人的使用觀點:

    1)上面兩個例子中我們使用goto是可以借鑑的,對程序的效率和美觀有一定的效果;

    2)對於一般的程序goto語句的功能儘量簡單,便於分析和代碼的整潔,如果不能帶來較大的優勢還是儘量少用;

    3)個人平時研究控制理論,對於任何事物覺得要麼是發散、要麼是收斂比較好分析處理問題,對于震蕩問題相對比較麻煩,所以對於如下圖2種goto的使用情景我是推薦的,前面說了只要我們控制好goto的靈活度就能夠為我們服務,那麼我們只需要規定在一個函數中其只是單向跳轉,我們對程序的把控能力就大大提高了。

    好了,今天的內容就到這裡吧,看完這個文章希望大家能夠有點收穫吧,也希望大家能幫忙傳播傳播,"再看"多點幾個,大家的認可都是我堅持寫作的動力源泉,寫作這條路上還是需要大家多多陪伴。

    感謝關注公眾號:"最後一個bug",我們下期見!

相關焦點

  • C語言 關鍵字(32+5+7)
    C語言32個關鍵字(C99新增5個、C11新增7個)按年份起始:auto break case char const continue default do double else enum
  • Emoji表情符號添72新丁:"打臉"、"流口水","孕婦"...你一定要試試
    你的手機裡很快就可以用上"與時俱進"的72新添Emoji表情符號。其中的"大神級"的表情符有:"在地板上打滾且大笑"及"一個在自拍的手"!蘋果和微軟反對"步槍"emoji制定新的表情符過程中一個值得玩味細節是,作為奧運會運動項目之一的"步槍射擊"emoji最後被踢出了列表。 "病毒式傳播"大神Buzzfeed News的透露的內幕是,只是蘋果公司和微軟反對的結果。這個消息在社交網絡上引起了討論。
  • 譚志剛的"淡"與"雅"
    第一次去,便被旁邊一家店的門楣上三個字聽吸引:"紫石齋"!我總是感覺,這三個字瀰漫著一種禪意,似在訴說著一個不可言說的故事。後來,通過了解,又知道了齋主譚志剛的名字。一年後,我去了衡陽,四年後又去了廣東。2008年,我開始上網,這時,在家鄉的紅網祁東論壇上,又遇到被祁東縣委宣傳部聘請為總版主的譚志剛。他有時在我的散文和雜文後面寫些簡短的評論,於是我們之間開始有了一些互動交流。
  • 楊冪"不雅視頻"風波,真相在這裡!
    5月14日,在楊冪發聲明否認,表示視頻主角並非楊冪之後,她又前往北京朝陽門派出所,就「楊冪不雅視頻」一事報案。為娛樂圈操碎了心的王思聰也對此事表態,他在微博聲稱自己看了9遍楊冪不雅視頻,力證醉酒視頻中的人不是楊冪。
  • 什麼是"惡",聽他講
    我不希望現實生活中的每一個人遇見這種事。但我認為,所有人都應該了解,直視它,以及它背後的那些人——我們與惡的距離The World Between Us本劇沒有用"惡"來搏人眼球,它讓你看到惡,而且讓你在看到之後,能夠有預知、預防的準備。但是,它又和以往犯罪主題的影視劇不同。它所聚焦的,並非兇手本人,或者兇手的作案手法與作案經過。
  • 被誤讀的"大表哥"丹·史蒂文斯
    等待是值得的,反差之下"大表哥"的顏值直登宇宙巔峰!話說,"大表哥"的暱稱是怎麼來的呢?當然是源於粉絲心目中的經典《唐頓莊園》。不過,粉絲們也許並沒有留意到,"大表哥"其實應是"大堂哥",絕非大表哥。如是姻親關係,他才可被稱為"表哥",但姻親關係在當時的社會背景下顯然絕無可能成為繼承人。那麼,一向明察秋毫英明無比的網友們為什麼會犯這個比較明顯的錯誤呢?這和中英兩國不同的文化背景及網友的思維定勢有關。
  • 惹翻臺妹的香港"性格"小店
    尤其濃縮其中的獨特文化,時常會讓不了解的人感到莫明其妙。這其中就包括,本地特產:"性格"小店。    現存最有名的當屬澳洲牛奶公司,一間名不符實,以服務態度粗暴,卻每天大排長龍的茶餐廳。影視作品中,最經典的當屬,周星馳和張學友合拍的《咖哩辣椒》中,對客人毫不妥協的捲毛茶餐廳老闆。
  • 均安,你為什麼這麼"窮"?
    招商部劉總監一聽這番話,馬上就表達了不同的意見,她說:"均安不窮,均安人的消費能力是不弱的,消費新百倫領跑鞋的能力是足夠的,你不要低估了均安的消費潛力。然而新百倫領跑的張經理接著說:"均安目前的發展實在是太落後了,你看看你們的街上,有幾個像樣的商場,在商業街上有幾個像樣的品牌,走在街上的有幾個人有好的購買力,同樣是順德的鎮,均安不僅不能與大良、容桂相比,比杏壇、勒流也差個檔次吧,你這樣的環境讓我怎麼到你那裡來開店?
  • 家裡在用"智能攝像頭"?也許你的一舉一動正在被直播,全世界網友隨時圍觀......
    點擊上方標題下「加拿大家園」可快捷關注家園君微信號:canadau  歡迎勾搭!
  • 關於楊冪的"不雅視頻",真相在這裡!自己進來比對...
    5月14日,在楊冪發聲明否認,表示視頻主角並非楊冪之後,她又前往北京朝陽門派出所,就「楊冪不雅視頻」一事報案。為娛樂圈操碎了心的王思聰也對此事表態,他在微博聲稱自己看了9遍楊冪不雅視頻,力證醉酒視頻中的人不是楊冪。
  • 從"酸甜女孩"到"破浪姐姐"你們了解張含韻嗎?是顏值還是歌聲
    與其他新事物無緣,在後期訪談節目,張含韻自己說道過自己被可愛定型了,而造成不可逆的局限範圍。你們知道嗎?通過《初戀未滿》讓人們想到原來我們所認識"酸甜女孩"張含韻也演戲同年,張含韻更第一次主演首部古裝電視劇《蘭陵王妃》,該劇整個故事環環扣人,帶有美劇節奏,情感又不失韓劇的糾結虐心
  • 抱歉,這部9.2分的"喪片"推晚了
    每年都會有新的潮流風颳來,而今年的除了"佛系"以外最有名的,可能就是"喪"。當然,這不是一個貶義詞。我認為,"喪"可能只是人們對於自己生活的一種自嘲,對社會的一種無力的妥協。昨天那部「她不知道名字的那些鳥兒」,喪氣十足。
  • "溫飽思Y欲"的正確打開方式!
    片如其名,「不倫食堂」不倫跟美食各佔了百分之五十。古人說"飽暖思淫慾",沒想到他們日本人在這方面的領悟力十分驚人。啥叫"唯美食最不可辜負",看了山寺隆一的日常你就會明白了。他有一個專門的筆記本整理了所有有名的美食和店鋪所在地。
  • 快速上手系列-C語言之基礎篇(一)
    吃飯用的筷子,到現在我都不知道它的由來,不知道它是在什麼歷史背景下誕生的有些東西還是有必要了解一下,比如,C語言所產生的代碼運行速度比彙編語言編寫的代碼運行速度稍慢一點,但還是有得一拼,同時C語言要比彙編語言編寫的代碼可讀性高,可移植性好。另外,相對於其他高級語言,比如C++、java、C#等來說,C語言編寫的代碼運行效率要高。
  • 練功,為何要懂得"服食"
    人,生活在天之下,地之上,《內經》中講,人生於"氣交"之中。人"吸"進來的是天之陽氣,"吃"進來的是地之陰氣。注意一下,這裡的天地陰陽已經是後天的陰陽了,不然到後面講先天陰陽的時候容易理解出偏。這個後天陰陽,就是水火。中醫常說,古人以水火立極,就是這個後天陰陽。先天陰陽是乾坤,這個學過易經的朋友都知道。
  • 日本"小電影"界最勤奮的男演員:跟拍男優"清水健"開工的一天!
    他曾經在Twitter上寫道:"在日本,像他這類的演員比孟加拉虎還要稀有。"他還寫道:"每個月4000部的新片,男演員的數量遠遠不夠,這個行業就像牆上的洞,必須要再大一點!"不過,Shimiken勤勞工作不只是為了賺錢,他表示對自己的感情生活不太滿意。身高1米63的Shimiken過去會和搭戲的女演員約會,他說:"我從來沒有談過一段正常的戀愛,感情總是結束得很糟糕。我認為,在這一行裡,漂亮的女孩是不會幸福的。他們會把漂亮女孩壓榨到一點價值也不剩,最後她們不得不退出。
  • "女主角"被人肉:阻攔救護車,私生活淫疑似還做"外圍女"?!
    事情發生在出租房的二樓央視新聞表示,中國駐多倫多總領事館高度關注此案件,正在積極協調處理各項相關事宜。"我們第一時間和警方進行了交涉,跟雙方家長迅速取得了聯繫並協助他們很快來到多倫多。""目前死者父母都已到達多倫多,我們正在協助他們處理後事。
  • 孫紅雷,你是真正的"老大",我服了!
    ",故事在跌宕起伏中走向圓滿。老大實難當,但金海能把老大當成這樣,實在可敬可嘆:1、對於金錢,取之有道,用之有道金海兩次對壞人"豪橫"來的七十多根金條全部散給手下的獄警兄弟了,自己一根不剩,把兄弟們感動的痛哭流涕。當然,最後獄警兄弟也反哺相報。
  • "命根子"與"勞什子"
    "命根子"與"勞什子"      一 從賈寶玉性格的典型意義看曹雪芹人性之壯麗 說不盡的《紅樓夢》。
  • 中美兩國巔峰對決的國祚密碼,"土"氣篇
    中美兩國都需要土運,可以說,誰"穩"誰勝。不管人家搞什麼夭蛾子,穩住陣腳、穩住民心就行。中國人自古盛讚一個人"穩重"的德行,不是沒有原因的。有人詬病中國在西方言論、西方文化方面,採取了一些封閉壓制的舉措,以前覺得這很不民主自由,怎麼就不敢大開國門,讓群眾多方浸潤,自行選擇呢?