各位,今天看了一個典型的代碼錯誤,比較有代表性,而且這也是大多數人在C程式設計中經常忽略的問題之一,拿出來與大家分享,希望大家以後避免類似的錯誤,代碼如下:
char c;while((c=getchar())!=EOF){...}
這段代碼的本意是用getchar函數讀取緩沖區字元直到結束,但是在編譯運作時,發現上面幾行代碼一直報錯!邏輯上沒問題啊,那這究竟錯在哪裡?讀者可以自己思考一下再往下看。
其實産生報錯的原因有兩點,一個是對getchar函數了解不到位,另一個是EOF的問題。
我們首先來說說getchar函數的問題,标準庫中給出了該函數的使用說明:在它讀取一個字元後,會将其轉換為int類型傳回,是以首先char c要改為int c,關于getchar的問題還沒講完,後面還要說。
我們接着來看看EOF的問題,初學者對它的了解經常會有偏差:首先它是一個宏,定義于頭檔案,為-1;其次它并不是很多人了解的檔案結束符,實際上它是一個标志位,差別于其他所有字元的存在,表示一種沒有其他字元的信号。
講到這裡,我們再回到getchar函數,由上面可以看出它的傳回值必須是一個能包含所有字元的資料類型,友善它表示任意字元和EOF等标志位。
是以,上面代碼的錯誤就很明顯了,可能有兩種情況:
1.如果編譯器中的char是有符号的且EOF被定義為-1,而恰好有字元等于0xff,那麼getchar就會提前結束。當然,如果輸入全部是7位以下的字元,那很長時間不會有錯誤。
2.如果編譯器中的char是無符号的,則實際的EOF值會被截斷,不再會識别為EOF,将會陷入無限循環。
這裡肯定會有人問我們鍵入-1來模拟EOF跳出循環不行嗎?實際上是不行的,-1是有-和1兩個字元組成的,而getchar一次隻能讀取一個字元,是以上述代碼EOF與從鍵盤輸入的字元無關,那這豈不是隻能死循環了?當然不是,我們可以通過按鍵組合ctrl+d或者ctrl+z來訓示結束,當然,這裡的按鍵組合輸入隻是我們的一種約定,不應該顯示檢查按鍵組合的值。
講到這裡大家應該明白了吧,希望對大家有所幫助,感謝耐心閱讀!