2013-08-28 224 views
38

我到處都看到 「它幾乎是相同的」,或者類似的東西...getc()vs fgetc() - 主要區別是什麼?

The GNU C Programming Tutorial

還有就是GNU C庫中的另一個函數調用的函數fgetc。除了getc通常作爲宏函數實現並且高度優化之外,它在大多數方面與getc相同,所以在大多數情況下更可取。 (在從標準輸入讀取的情況下,getc的速度與fgetc一樣快,因爲與計算機可以讀取輸入的速度相比,人類輸入的速度較慢,但​​是當您從不是由人類交互式生成的數據流讀取時, fgetc可能更好。)

其他區別是什麼?我聽說他們每個人都有不同的實現(其中一個可以用作宏),但是,是什麼使他們在標準C庫(或規範)中變得不同(或不同)?

+1

好信息在這裏:http://stackoverflow.com/questions/5186457/c-fgets-versus-fgetc-for-reading-line – dcaswell

+3

@ user814064,你的鏈接提到'fgets' vs'fgetc',OP在問關於'getc' vs'fgetc' –

+0

getc()在那個鏈接中被提及,以及它的優點。 – dcaswell

回答

38

Advanced Programming in Unix Environment

...

getcfgetc之間的區別是getc可以 作爲宏來實現,而fgetc不能作爲 宏來實現。這意味着三件事:

  • getc的參數不應該是一個帶有副作用的表達式。
  • 由於fgetc保證是一個函數,我們可以採取它的地址。這允許我們將fgetc的地址作爲參數 傳遞給另一個函數。
  • 調用fgetc的時間可能比調用getc的時間要長,因爲調用函數通常需要更多時間。

...

+0

我起來+1,但是:爲什麼他們都在標準庫中?爲什麼不能成爲一個宏? –

+1

那麼'getc'如何被定義爲一個宏呢?任何指針? – day

+0

@你的意思是「如何」,如「實現細節是什麼」或「你怎麼能夠做到這一點(道德上或技術上)」? –

2

基本上是相同的(或類似的不足以打擾)。你應該看看它們的實現:GNU libcMUSL libc是自由軟件實現。他們現在可以實現爲內聯函數(與宏一樣快)。

而且我不會打擾那麼多。在現實生活中,I/O主要受硬件限制(例如訪問磁盤的時間)。

13

好像差別是,在案件99.9%,毫無意義。

可能有所作爲的一點 - The man pagegetc() may be implemented as a macro which evaluates stream more than once

它可能會導致奇怪的行爲在某些(不是很有用)的情況下,例如:

FILE *my_files[10] = {...}, *f=&my_files[0]; 
for (i=0; i<10; i++) { 
    int c = getc(f++); // Parameter to getc has side effects! 
} 

如果getc評估不止一次f++多,就會提前超過每一次迭代更f。相比之下,fgetc在這種情況下是安全的。

相關問題