2013-05-06 94 views
8

我新的編程,啓動了與Objective-C的,但已經決定回到基礎進一步進展之前。我花了一些時間在C上,並且正在通過指針混淆掙扎。我的問題是關於如何實現fgets的K &(p165,第二版)。下面的代碼是直接從我的幾條評論的文本。與fgets實現(K&R)

char* fgets(char* s, int n, FILE *iop) 
{ 
    register int c; 
    register char* cs; 
    cs = s; 

    while(--n > 0 && (c = getc(iop)) != EOF) 
    { 
    // put the input char into the current pointer position, then increment it 
    // if a newline entered, break 
    if((*cs++ = c) == '\n') 
     break;   
    } 

    *cs = '\0'; 
    return (c == EOF && cs == s) ? NULL : s; 
} 

1)我們通過一個char * s到的與fgets功能,在其位置,我們存儲用戶輸入。爲什麼需要聲明本地char * cs - 然後將其初始化爲s?爲什麼我們不能在if語句中直接操作/添加到s?看到cs被初始化爲s,是不是將cs添加到完全相同的東西?

2)與上述系杆在...在函數返回時,進行測試以查看是否CS ==秒。爲什麼這是必要的?

我想我可能會丟失一些非常基本的 - 我這樣做了檢查和谷歌,但不能完全弄清楚。謝謝!

+2

「從Objective-C開始,但決定在進一步發展之前回到基礎知識」 - 非常好,**每個初學者都應該這樣做。** – 2013-05-06 11:31:57

+1

我剛開始覺得我正在步步爲營在Obj-C中。自從回到C後,我再次感受到了一個完整的klutz,但是儘管我反覆敲打了分段故障和奇怪的程序行爲,但這絕對值得。 – drjimmie1976 2013-05-06 18:13:39

+0

這是最值得的。掌握C對於理解Objective-C是不可避免的。 – 2013-05-06 18:28:03

回答

7

這是因爲在最後一行,cs == s的檢查。該比較檢查修改的指針cs與原始s以查看我們是否讀過任何字符。如果我們沒有,那麼我們返回NULL。

通過使用cs整個原始指針s被保留。如果直接操作s*s++而不是*cs++),那麼我們必須找到另一種方法來檢查是否讀取了任何字符。

人們也可以說,這是一個很好的做法,獨自離開函數的參數,並把它們作爲const。一些程序員遵循這種做法來提高代碼清晰度。

+0

非常感謝約翰。這使得意圖更清楚,但是如果我可以再提幾個問題......當'cs'被賦予'cs = s'時,我認爲指針現在指向完全相同的內存區域;因此執行'* cs ++'將完全等同於'* s ++'。這個假設是錯誤的嗎? – drjimmie1976 2013-05-06 17:46:57

+0

對不起,我的評論超時了,我也做了評論標記錯誤....這就是爲什麼我不明白最後一行。我認爲看到兩個指針是「共享」的,那麼當c == cs表達式評估時它們將是相同的。提前致謝。 – drjimmie1976 2013-05-06 17:54:52

+0

@ GasMan14他們在作業後指向同一地址,這是正確的。不過,'* cs ++'不會修改's'。確保你理解優先級:'* cs ++'等於'*(cs ++)'而不是'(* cs)++'。 'cs ++'遞增'cs',使其指向下一個地址,然後'*'解引用該地址。 's'沒有改變,因爲's'和'cs'是兩個獨立的變量。如果語句是'(* cs)++',那麼*會*改變'* s'的值。 (請注意,不是''',而是'* s'。) – 2013-05-06 23:00:36