偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

C語(yǔ)言函數(shù)調(diào)用:【錯(cuò)誤碼】和【返回值】傳遞的小思考

開(kāi)發(fā) 后端
C 語(yǔ)言是一門(mén)面向過(guò)程的編程語(yǔ)言,通過(guò)一個(gè)又一個(gè)函數(shù),把計(jì)算、過(guò)程控制等邏輯,包裝成一個(gè)個(gè)獨(dú)立的處理單元。

C 語(yǔ)言是一門(mén)面向過(guò)程的編程語(yǔ)言,通過(guò)一個(gè)又一個(gè)函數(shù),把計(jì)算、過(guò)程控制等邏輯,包裝成一個(gè)個(gè)獨(dú)立的處理單元。

既然是函數(shù)調(diào)用,就一定會(huì)有參數(shù)和返回值的傳遞問(wèn)題,因此也就產(chǎn)生了多種不同的編程范式,比如:

  • Posix 風(fēng)格:函數(shù)返回值只用來(lái)表示成功(0)或失敗(非0),其他的輸出結(jié)果都使用參數(shù)來(lái)傳遞。
  • Unix 風(fēng)格:函數(shù)返回值即包括錯(cuò)誤代碼,也包括有用的輸出結(jié)果。
  • GAI 風(fēng)格:與 Posix 有點(diǎn)類(lèi)似,函數(shù)執(zhí)行成功時(shí)返回0,否則就返回非0。

這篇文章就來(lái)輕松一下,聊一聊這些函數(shù)調(diào)用范式在開(kāi)發(fā)過(guò)程中的一些小思考。

我們假設(shè)有一個(gè)算法函數(shù),輸入兩個(gè)整型參數(shù),輸出一個(gè)整型結(jié)果,并且輸出一個(gè)錯(cuò)誤代碼。

第一種:輸入、輸出結(jié)果和錯(cuò)誤碼全部通過(guò)參數(shù)傳遞

既然所有的信息都是通過(guò)參數(shù)來(lái)傳遞的,那么函數(shù)定義就應(yīng)該是下面這樣:

  1. void func1(int a, int b, int *result, int *err_code) 
  2.     int c = a + b; 
  3.     *result = c; 
  4.     err_code = 0;  // 沿用 Linux 中的習(xí)慣,0 表示沒(méi)有發(fā)生錯(cuò)誤。 

因?yàn)椴恍枰祷厝魏螖?shù)據(jù),因此函數(shù)簽名的返回類(lèi)型就是 void 。

因?yàn)檎{(diào)用者需要獲取輸出結(jié)果和錯(cuò)誤碼,因此在形參中, result和err_code需要傳遞指針類(lèi)型的變量。

面對(duì)這樣的函數(shù)簽名,調(diào)用者就必須顯示的定義兩個(gè)變量result和err_code,用來(lái)接收函數(shù)的輸出。

  1. // 調(diào)用者代碼 
  2.  
  3. int result, err_code; 
  4. func(1, 2, &result, &err_code); 
  5. if (0 == err_code) 
  6.     printf("Success. result = %d \n", result); 
  7. else 
  8.     printf("Failed. err_code = %d \n", err_code); 

這種函數(shù)范式的優(yōu)點(diǎn)就是:在調(diào)用形式上統(tǒng)一,無(wú)論參數(shù)類(lèi)型是什么(基礎(chǔ)類(lèi)型、結(jié)構(gòu)體等待),都是整齊劃一的函數(shù)調(diào)用寫(xiě)法。

缺點(diǎn)就是有點(diǎn)累贅。

面對(duì)任何一個(gè)函數(shù),調(diào)用者都必須定義一個(gè)err_code變量傳遞進(jìn)去。

如果一個(gè)函數(shù)是過(guò)程控制類(lèi)型的,壓根就不會(huì)產(chǎn)生什么錯(cuò)誤碼,這樣的函數(shù)調(diào)用就顯得很臃腫,因?yàn)檎{(diào)用者壓根就不需要檢查錯(cuò)誤碼。

第二種:函數(shù)返回值表示錯(cuò)誤碼

也就是把第一種方式中的err_code參數(shù),通過(guò)函數(shù)返回值賦值給調(diào)用者。

這種函數(shù)編程范式還是比較常見(jiàn)的,返回值只表示錯(cuò)誤碼,其他的輸出結(jié)果都通過(guò)參數(shù)引用(指針)來(lái)傳遞。

  1. int func2(int a, int b, int *result) 
  2.     int c = a + b; 
  3.     *result = c; 
  4.     return 0;   // 返回錯(cuò)誤碼 

這樣的函數(shù)范式跟POSIX風(fēng)格很像了。

面對(duì)這樣的函數(shù),調(diào)用者的寫(xiě)法就會(huì)變成這樣:

  1. // 調(diào)用者代碼 
  2.  
  3. int result, err_code; 
  4. err_code = func2(1, 2, &result); 
  5. if (0 == err_code) 
  6.     printf("Success. result = %d \n", result); 
  7. else 
  8.     printf("Failed. err_code = %d \n", err_code); 

看起來(lái)好像跟第一種方式?jīng)]有什么本質(zhì)區(qū)別,但是再看一下下面這樣的寫(xiě)法呢:

  1. // 調(diào)用者代碼 
  2.  
  3. int result; 
  4. if (0 == func2(1, 2, &result)) 
  5.     printf("Success. result = %d \n", result); 
  6. else 
  7.     printf("Failed.\n"); 

這樣的代碼風(fēng)格,在Linux中是不是很常見(jiàn)?當(dāng)不需要處理錯(cuò)誤碼時(shí),這樣的編程方式會(huì)更方便一些。

第三種:函數(shù)返回值表示輸出結(jié)果

也就是把第一種方式中的result參數(shù),通過(guò)函數(shù)返回值賦值給調(diào)用者。

  1. int func3(int a, int b, int *err_code) 
  2.     int c = a + b; 
  3.     err_code = 0; 
  4.     return c; 

這有點(diǎn)類(lèi)似Unix中的風(fēng)格:

返回結(jié)果中包括了有用的數(shù)據(jù),但是它有一個(gè)局限:返回結(jié)果必須與錯(cuò)誤碼的類(lèi)型一致。

另外還有一個(gè)問(wèn)題:如果 int 型的返回結(jié)果也可能是負(fù)數(shù), 所以 Unix 中還必須使用另一個(gè)全局變量 errno 來(lái)單獨(dú)存儲(chǔ)錯(cuò)誤碼,存在線程安全問(wèn)題(可以使用線程局部存儲(chǔ)來(lái)解決)。

面對(duì)這樣的函數(shù)簽名,調(diào)用者的調(diào)用方式如下:

  1. // 調(diào)用者代碼 
  2.  
  3. int result, err_code; 
  4. result = func3(1, 2, &err_code)) 
  5.  
  6. if (0 == err_code) 
  7.     printf("Success. result = %d \n", result); 
  8. else 
  9.     printf("Failed.\n"); 

這種方式的缺點(diǎn)與第一種一樣:必須定義一個(gè)變量 err_code,來(lái)接收錯(cuò)誤碼。

在不必要檢查錯(cuò)誤碼的場(chǎng)合中,顯得有點(diǎn)多此一舉。

小結(jié)

以上的這三種函數(shù)調(diào)用方式,沒(méi)有好壞之分,只與每一位開(kāi)發(fā)者的編碼習(xí)慣有關(guān)系。

而且在實(shí)際的項(xiàng)目代碼中,這三種方式都能看得到。

如果函數(shù)輸出結(jié)果是結(jié)構(gòu)體呢?

剛才討論的三種方式中,函數(shù)輸出結(jié)果reuslt是一個(gè)整型,如果它是一個(gè)結(jié)構(gòu)體類(lèi)型的變量,那么哪一種方式相對(duì)比較好呢?

這就要注意另外兩點(diǎn)了:

結(jié)構(gòu)體的賦值是需要時(shí)間開(kāi)銷(xiāo)的;

結(jié)構(gòu)體賦值時(shí),需要考慮深拷貝、淺拷貝的問(wèn)題;

當(dāng)看完以上幾個(gè)小思考時(shí),是不是覺(jué)得特別簡(jiǎn)單、不屑一顧?

不妨繼續(xù)思考一步:在我們的實(shí)際編程過(guò)程中,是不是每次能夠注意、遵守這些小細(xì)節(jié)問(wèn)題呢?

如果團(tuán)隊(duì)中沒(méi)有強(qiáng)制的代碼規(guī)范,同事之間不會(huì)code review,我們是不是都會(huì)選擇偷懶、放過(guò)自己呢?我就是^-^

本文轉(zhuǎn)載自微信公眾號(hào)「IOT物聯(lián)網(wǎng)小鎮(zhèn)」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系IOT物聯(lián)網(wǎng)小鎮(zhèn)公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2025-01-02 10:37:13

2025-01-17 10:52:26

定義函數(shù)編程Python

2017-09-05 14:59:34

2019-09-19 09:41:58

C語(yǔ)言Go語(yǔ)言Java

2022-12-28 08:17:19

異常處理code

2020-06-30 11:36:45

錯(cuò)誤碼合理開(kāi)發(fā)

2010-07-20 11:37:00

Perl函數(shù)返回值

2023-01-29 23:51:07

微服務(wù)框架Go

2010-07-21 10:32:05

Perl函數(shù)返回值

2017-11-20 11:53:38

CDN406錯(cuò)誤故障

2021-08-13 11:31:23

HTTP

2009-11-17 16:16:59

PHP遞歸函數(shù)

2009-09-07 03:07:11

C# Main方法

2011-07-19 17:33:53

存儲(chǔ)過(guò)程javaibatis

2021-12-19 23:58:51

Golang語(yǔ)言返回值

2024-01-29 00:30:00

C語(yǔ)言代碼數(shù)組

2021-08-06 14:35:26

鴻蒙HarmonyOS應(yīng)用

2009-08-25 10:59:00

C#調(diào)用函數(shù)顯示值

2025-05-29 10:30:00

C++編程recv

2016-11-04 08:53:05

androidjava單元測(cè)試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)