2013-11-20 45 views
-1

getc() VS fgetc()爲什麼fputc()當putc()?

putc() VS fputc()

它們之間的主要區別是什麼?

我聽說這兩個函數都做了幾乎相同的事情,除了getc()可以用作宏。這是什麼意思?

如果他們是相同的,爲什麼使用兩個功能在那裏做同樣的事情?

任何幫助將認真感激?

回答

0

根據Kernighan的書,putc等同於fputc,但是putc可以作爲一個宏來實現,而且putc可以多次評估它的流參數。

putc和fputc之間的區別在於,通過使用putc,您可能會運行宏本身不安全的版本,因爲它可能必須多次評估其流參數。這會導致大多數人不知道的併發症,因此不會注意,所以fputc更好用。 fputc的宏沒有這個問題。

+0

是不是非f-函數簡單的宏與預先提供'stdin'的參數之一? –

+0

@BitFiddlingCodeMonkey不,我會在答案中添加一個例子 – Random832

0

至少對於fprintf()很明顯,因爲您可以指定FILE*寫入的位置。 printf() print to stdout

其他2X2功能在使用上確實是等效的。

1

首先,printf vs fprintf是不同的:fprintf支持文件參數,printf轉到stdout。

fputc和fgetc的原因是,在歷史實現中,putc和getc是不止一次評估參數的宏版本。例如,the version on Unix V7

#define getc(p) (--(p)->_cnt>=0? *(p)->_ptr++&0377:_filbuf(p)) 
#define putc(x,p) (--(p)->_cnt>=0? ((int)(*(p)->_ptr++=(unsigned)(x))):_flsbuf((unsigned)(x),p)) 

每一個「P」在那裏被替換爲你把論點表達 - 所以,如果它有副作用(如你調用的函數來獲取文件,或者迭代在++運算符的文件列表中),它將被多次調用並可能在不同的文件上運行。

一些現代系統(例如FreeBSD或OSX)仍然會這樣做,但通常只在「解鎖」版本中使用,因爲標準getc/putc函數必須是線程安全的。解鎖版本用於庫函數內部的性能,因此鎖在庫函數的頂部只能獲取一次(因此,當您調用printf時,它不必調用fputc數百次,每次都執行鎖定時間)。