getc()
VS fgetc()
爲什麼fputc()當putc()?
putc()
VS fputc()
它們之間的主要區別是什麼?
我聽說這兩個函數都做了幾乎相同的事情,除了getc()可以用作宏。這是什麼意思?
如果他們是相同的,爲什麼使用兩個功能在那裏做同樣的事情?
任何幫助將認真感激?
getc()
VS fgetc()
爲什麼fputc()當putc()?
putc()
VS fputc()
它們之間的主要區別是什麼?
我聽說這兩個函數都做了幾乎相同的事情,除了getc()可以用作宏。這是什麼意思?
如果他們是相同的,爲什麼使用兩個功能在那裏做同樣的事情?
任何幫助將認真感激?
根據Kernighan的書,putc等同於fputc,但是putc可以作爲一個宏來實現,而且putc可以多次評估它的流參數。
putc和fputc之間的區別在於,通過使用putc,您可能會運行宏本身不安全的版本,因爲它可能必須多次評估其流參數。這會導致大多數人不知道的併發症,因此不會注意,所以fputc更好用。 fputc的宏沒有這個問題。
至少對於fprintf()
很明顯,因爲您可以指定FILE*
寫入的位置。 printf()
print to stdout
。
其他2X2功能在使用上確實是等效的。
首先,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數百次,每次都執行鎖定時間)。
是不是非f-函數簡單的宏與預先提供'stdin'的參數之一? –
@BitFiddlingCodeMonkey不,我會在答案中添加一個例子 – Random832