C語言 超詳細講解庫函數(shù)
1 返回整數(shù)的getchar函數(shù)
代碼:
#include<stdio.h> int main() { char c; while((c = getchar())!=EOF)//getchar函數(shù)的返回值為整型 putchar(c); return 0; }
上述代碼有三種可能:
- 某些合法的輸入字符在被“截斷”后使得c的取值與EOF相同,程序將在復制的中途停止。
- c根本不可能取到EOF這個值,陷入死循環(huán)。
- 程序表面上能夠正常工作,但完全是因為巧合。盡管函數(shù)geutchar的返回結果在賦給char類型的變量c時會發(fā)生“截斷”操作,但在許多編譯器下,它們在比較表達式中并不是比較c與EOF,而是比較getchar函數(shù)的返回值與EOF!,如果編譯器采取的是這種做法,上面的例子就能夠正常運行了。
2 更新順序文件
在使用r+同時進行寫入和讀出文件的操作時,要使用fseek移動指針才行,因為在進行寫入和讀取的同時,文件指針指向的位置發(fā)生了改變。
3 緩沖輸出與內存分配
程序輸出有兩種方式:一種是即時處理方式;另一種是先暫存起來,然后再大塊寫入的方式。
setbuf(stdout,buf);
語句將通知輸入/輸出庫。所有寫入stdout的輸出都應該使用buf作為輸出緩沖區(qū),直到buf緩沖區(qū)被填滿或者程序員直接調用fflush(對于由寫操作打開的文件,調用fflush將導致輸出緩沖區(qū)的內容被實際的寫入該文件),buf緩沖區(qū)種的內容才實際的寫入stdout中。緩沖區(qū)的大小由系統(tǒng)頭文件<stdio.h>中的BUFSIZ定義。
下面是實例:
#include<stdio.h> int main() { int c; char buf[BUFSIZ]; setbuf(stdout,buf); while((c = getchar())!=EOF) putchar(c); }
上面這個程序是錯誤的,因為buf緩沖區(qū)最后一次清空是再main()函數(shù)結束之后,在將控制權交給操作系統(tǒng)之前,C運行時庫所必須進行清理工作的一部分。但是,在此之前buf字符數(shù)組已經(jīng)被釋放。
兩種解決方案:
static char buf[BUFSIZ];
setbuf(stdout,(char*)malloc(BUFSIZ)); //此處不需要檢查malloc函數(shù)調用是否成功,因為setbuf函數(shù)的第二個參數(shù)取值可以為NULL,此時標準輸出不需要進行緩沖。
4 庫函數(shù)
C語言實現(xiàn)中包括signal庫函數(shù),將其作為捕獲異步時間的一種方式。
#include<signal.h>//需要引用的頭文件 signal(signal type , handler function);
這里的signal type代表系統(tǒng)頭文件signal.h中定義的某些常量,這些常量用來標識signal函數(shù)將要捕獲的信號類型。這里的handler function是當指定的事件發(fā)生時,將要加以調用的事件處理函數(shù)。
注意:信號甚至可能出現(xiàn)在某些復雜庫函數(shù)(如malloc)的執(zhí)行過程中。。因此,從安全的角度考慮,信號的處理函數(shù)不應該調用上述類型的庫函數(shù)。
例如:假設malloc函數(shù)的執(zhí)行過程被一個信號中斷。此時,malloc用來跟中可用內存的數(shù)據(jù)結構很可能只有部分被更新。如果signal處理函數(shù)再調用malloc函數(shù),結果可能是malloc函數(shù)用到的數(shù)據(jù)結構完全崩潰,后果不堪設想。
結論:信號非常復雜棘手,而且具有一些從本質上而言不可移植的特性。所以我們應該讓signal處理的函數(shù)盡可能的簡單,并將它們組織在一起,這樣,當需要適應一個新系統(tǒng)時,我們可以很容易的進行修改。
練習
問:當一個程序異常終止時,程序輸出的最后幾行常常會丟失,原因是什么?我們能夠采用怎樣的措施來解決這個問題?
答:一個異常終止的程序可能沒有機會來清空輸出其緩沖區(qū),因此,該程序生成的輸出可能位于內存中的某個位置,但卻永遠不會被寫出了。在某些系統(tǒng)上,這些無法被寫出的輸出數(shù)據(jù)可能長達好幾頁。
對于調試這類程序的編程人員來說,這種丟失輸出的情況經(jīng)常會誤導他們,因為這會造成這樣一種印象,即程序發(fā)生失敗的時刻比實際上運行失敗的真正時刻要早得多。**解決方案就是在調試時強制不允許對輸出進行緩沖。**解決方案如下:
setbuf(stdout,(char*)0);
這個語句必須在任何輸出被寫入stdout(包括任何對printf函數(shù)的調用)之前執(zhí)行。該語句最恰當?shù)奈恢镁褪亲鳛閙ain函數(shù)的第一個語句。
下面程序的作用是把它的輸入復制到輸出:
#include<stdio.h> int main() { register int c; while((c = getchar())!=EOF) putchar(c); return 0; }
把代碼改為下面的代碼,程序依然能夠正確運行,但是慢了許多,這是為什么?
#define EOF -1 int main() { register int c; while((c = getchar())!=EOF) putchar(); return 0; }
函數(shù)調用需要花費較長的程序執(zhí)行時間,因此getchar常常被實現(xiàn)為宏。這個在stdio.h中定義,因此一個程序沒有包含stdio.h頭文件,在所有fgetchar宏出現(xiàn)的地方,都用getchar函數(shù)調用來替換getchar宏。這個程序之所以變慢,就是因為函數(shù)調用所導致的開銷增多。同樣的依據(jù)也適用于putchar。
到此這篇關于C語言 超詳細講解庫函數(shù)的使用方法的文章就介紹到這了,更多相關C語言 庫函數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
opencv3/C++ 使用Tracker實現(xiàn)簡單目標跟蹤
今天小編就為大家分享一篇opencv3/C++ 使用Tracker實現(xiàn)簡單目標跟蹤,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-12-12