函數(shù)之間的通信方式

函數(shù)之間的通信方式

程序無外乎由變量和函數(shù)組成,前者負責保存和組織數(shù)據(jù),后者負責業(yè)務邏輯,即操作這些數(shù)據(jù)以獲得期望的結果。函數(shù)彼此獨立,但又不孤立,而是需要同其他函數(shù)進行交流,以便協(xié)同工作。因此,理解函數(shù)之間的通信方式顯得尤為重要。

通信方式的種類

所謂函數(shù)的通信方式,就是一個函數(shù)將值傳遞給另一個函數(shù)的渠道。有三種:

  • 函數(shù)的返回值:調用函數(shù)可以直接獲得被調用函數(shù)的返回值。
  • 函數(shù)的參數(shù):以引用傳遞的方式將一個指針傳遞給被調用函數(shù),后者將需要返回給調用函數(shù)的值放入其中。
  • 全局變量:任意函數(shù)都可以訪問,多用在兩個函數(shù)之間需要進行通信,但又不直接調用對方的情況下。

本文重點講解前兩項。

getint函數(shù)

K&R中有一個很好的例子,說明了返回值和參數(shù)這兩個通信方式(以下簡稱通道)之間的的區(qū)別和聯(lián)系。(K&R Section5.2 P95)

需要設計一個名為getint()的函數(shù),作用是從標準輸入流中讀取一個數(shù)字字符串(整數(shù)),然后將其轉化為相應整數(shù)數(shù)值。
從程序設計的角度來講,很明顯這個函數(shù)在工作期間會遇到若干種情況,而且需要向它的調用方說明這些情況,這些情況有:
1. 成功轉換字符串,得到一個需要被返回的數(shù)值。
2. 轉換失敗,因為讀取到的字符不是數(shù)字。
3. 轉換失敗,因為讀取到了EOF。

問題是,以上情況并不互相排斥,而是有可能同時出現(xiàn)。
例如,對于"12345qwer"這樣一個字符串,"12345"的部分可以被成功讀取;而"qwer"部分會因為不是數(shù)字而轉換失敗。這是函數(shù)應該返回"12345"表示的數(shù)值,并且告訴調用方猶豫后續(xù)字符不是數(shù)字,無法繼續(xù)。

又例如,對于"-1"這樣一個字符串來說,它后面如果緊跟著EOF,那么函數(shù)就需要在返回-1的同時,還需要告訴調用方它遇到了EOF而終止。EOF是-1,恰好同字符串所代表的數(shù)值相同,如果利用返回值進行傳遞,肯定會造成誤解。
很明顯,如果所有的可能情況都通過返回值進行傳遞,是不可能的。這是就要同時利用返回值和參數(shù)進行傳遞: 
返回值:負責說明轉換是否成功,以及錯誤的原因(錯誤原因互相排斥)。
參數(shù):在轉換成功的情況下,負責將轉換后的數(shù)值傳遞出去。

上面的分析可以概括為:

  • 轉換成功(返回一個正數(shù)):
    • 轉換結果(利用參數(shù)傳遞出去)
  • 由于讀取到EOF而失敗(返回-1):
  • 由于讀取到非數(shù)字字符失敗(返回0):

詳細代碼如下

#include <stdio.h>
#include <ctype.h>

/**
 *  從標準輸入流中讀取一個整數(shù)數(shù)字字符串,并將其轉換為對應的整數(shù)數(shù)值
 *
 *  @param pn int型指針,用于將轉換所得的整數(shù)數(shù)值傳遞出去
 *
 *  @return 如果輸入的字符串含有整數(shù),返回一個正整數(shù)(取決于數(shù)字后面的第一個字符,如有);如果不含有合法數(shù)字,返回0;如果遇到EOF,返回-1
 */
int getint(int *pn);


int bgetchcar(void); // 等同于getc
void bungetchar(int n); // 等同于ungetc

int main(int argc, const char * argv[]) {
    
    int x = 0;
    int r = getint(&x);
    
    printf("r:%d----x:%d\n", r, x);
    
    
    return 0;
}

int getint(int *pn)
{
    int c, sign;
    
    while (isspace(c = bgetchcar())) { // 跳過空格
        ;
    }
    if (!isdigit(c) && c != EOF && c != '+' && c != '-') {
        bungetchar(c); // 不是數(shù)字,退回最近讀到的字符到輸入流中
        return 0;
    }
    
    sign = (c == '-') ? -1 : 1; // 嘗試記錄符號
    if (c == '+' || c == '-') { // 如果當前讀到的是符號,則繼續(xù)讀取下一個字符
        c = bgetchcar();
    }
    for (*pn = 0; isdigit(c); c = bgetchcar()) { // 開始逐個讀取數(shù)字,直到讀取到一個不是數(shù)字的字符為止
        *pn = (*pn) * 10 + (c - '0'); // *10負責提升位數(shù),c - '0'得出每一位的數(shù)字
    }
    
    *pn *= sign; // 糾正數(shù)值的正負
    
    if (c != EOF) { // 如果最后讀取到的字符不是EOF
        bungetchar(c); // 則將這個字符退回到輸入流中
    }
    return c;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370

推薦閱讀更多精彩內容