大多數庫函式的使用都不會有什麼問題,它們的意義和用法明白而直接,基本上都能正確的使用它們,但也有一些例外情況,如一些常用到的庫函式表現出來的行為方式往往有悖於使用者的本意(尤其是我們初學者),今天我們就來討論一些常用到的庫函式,以及使用過程中可能出錯之處。
我們先來看乙個簡單的例子:
# include
int main(void)
複製**
getchar 函式在一般情況下返回的是標準輸入檔案中的下乙個字元,當沒有輸入時返回eof,這個程式看似是把標準輸入複製到標準輸出,實則不是,原因在於程式中的變數c 被宣告為char 型別,而不是int型別,這意味著無法容下所有的字元,特別是無法容下eof。
因此,最終結果有兩種可能: 一種是,某些合法的輸入字元在被截斷後是的c的取值與eof 相同。
另一種是,c 根本不可能取到eof這個值。
總結:對於第一種情況,程式在檔案複製的中途終止;對於後一種情況,程式將陷入乙個死迴圈。實際上,還存在了第三種情況,程式表面上似乎能夠正常工作,那是因為巧合。儘管函式getchar的返回記過在賦給char型別的變數c時會發生截斷操作。將返回值的地位資料賦給c,但與eof的比較不是c,而是getchar的返回值,編譯器如果採用這種做法,上面的程式就可以正常執行了。
許多系統中的標準輸入/輸入庫都允許程式開啟乙個檔案,同時進行寫入和讀取的操作。
file * fp; fp = fopen(file,」r+」); 上面的例子**開啟了檔名由變數file指定的檔案,對於訪問許可權的設定表明程式希望對這個檔案進行輸入和輸出操作。
程式設計者也許認為,程式一旦執行上述操作完畢,就可以自由的交錯進行讀出和寫入的操作.但事實上並不是我們想象的那樣,我們在進行了讀操作或者寫操作之後,都會改變檔案指標的位置。因此,先要同時進行輸入和輸出操作,必須使用 fseek 函式改變檔案指標的位置。
很多庫函式,特別是與作業系統相關的,當執行失敗時會通過乙個名稱為 errno 的外部變數,通知程式該函式呼叫失敗。請看下面的額例子:
/*呼叫庫函式*/
if (errno)
/*處理錯誤*/
複製**
這是乙個簡單的錯誤處理程式,看起來沒問題,然而卻是錯誤的。出錯原因在於,在庫函式呼叫沒有失敗的情況下,並沒有強制要求庫函式一定設定errno為0,這樣errno 的值就可能是前乙個執行失敗的庫函式設定的值。我們對**做了一下調整,看似正確,但可能還是錯誤的:
errno = 0;
/*呼叫庫函式*/
if(errno)
/*出錯處理*/
複製**
原因在於,庫函式在呼叫成功後,即沒有強制要求對errno清零,同時也沒有禁止設定errno。因為在呼叫乙個函式的時候,可能會在內部呼叫另乙個函式,此時可能設定errno。
所以,在呼叫庫函式時,我們應該首先檢測作為錯誤指示的返回值,確定程式已經執行失敗。然後,在檢查errno,來搞清楚出錯原因:
/* 呼叫庫函式 */
if(返回的錯誤值)
檢查errno
複製**
實際上,所有的c語言實現中都包括有signal庫函式,作為捕獲非同步事件的一種方式。要使用該庫函式,需要在原始檔中加上#include
以引入先關的宣告,要處理乙個特定的signal(訊號),可以這樣呼叫signal函式:
signal(signal type, handle function);
--signal type 代表要處理的訊號.
--handle function 代表訊號發生時,呼叫的事件處理函式.
複製**
在許多c語言實現中,訊號是真正意義上的」非同步」。從理論上說,乙個訊號可能在c程式執行期間的任何時刻發生,訊號甚至可能出現在某些複雜的庫函式(如malloc)的執行過程中。因此,訊號的處理函式不應該呼叫上述型別的庫函式。
我們需要讓signal處理函式盡可能的簡單,並將它們組織在一起,這樣,當需要適應乙個系統時,我們可以很容易的進行修改。
封裝容易出錯的幾個問題!
1 原版容易出的問題 23 原版出錯的原因大部分是因為 中心wm的原因,禁用這兩個服務基本上就可以解決.45 原版系統的朋友請以管理員身份開啟cmd,輸入下面的命令就可以了67 8910 net stop wmpnetworksvc 1112 停止wmpnetworksvr服務 1314 net s...
c語言中容易出錯的幾個地方
1 常量與變數判斷是否相等時,一般把常量寫在前面,這樣若少寫乙個 會出現錯誤提示,方便改正。2 判斷浮點數是否相等時,不允許用 因為有些小數部分因為二進位制轉換導致不能儲存準確的值。一般設定乙個精度來做判斷,如果兩數之差的絕對值處於精度之外的話,我們可以看做兩個數相等。const double ex...
c c 裡的幾個容易困擾的點
下面列出幾個c c 語言裡比較困擾工程師的語言點,1.為什麼需要volatile關鍵字?從字面上解釋,volatile是 易變的,不穩定的 通過這個關鍵字的定義,告訴編譯器這個值一定要從指定的位址的memory直接讀取,否則讀取的值可能是data cache中儲存的值,和實際位址memory中的值可...