程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言中fgetc、fputc和getc、putc的區別是什麼,getcputc

C語言中fgetc、fputc和getc、putc的區別是什麼,getcputc

編輯:關於C語言

C語言中fgetc、fputc和getc、putc的區別是什麼,getcputc


  看書的時候,發現了這四個函數,想知道他們的不同。結果上網查發現很多人說fgetc、fputc的f代表的是file,就是這兩個函數是和文件有關的!但是一看他們的函數聲明,如下圖:

  

  

  發現他們的參數裡面都有文件指針啊!後來又去翻了翻APUE,發現那個f代表的其實是function,這是怎麼一回事呢,且聽我慢慢道來!

  fgetc和getc他們的區別並不是在他們的使用上,而是在他們的實現上!具體來說,就是帶f的(fgetc、fputc)實現的時候是通過函數來實現的,而不帶f(putc、getc)的,實現的時候是通過宏定義來實現的!關於他們的不同點,就拿getc和fgetc來說,APUE(p115)上是這麼寫的:

  <1>.getc的參數不應當是具有副作用的表達式。

  <2>.因為fgetc一定是一個函數,所以可以得到其地址。這就允許將fgetc的地址作為一個參數傳送給另一個函數。

  <3>.調用fgetc所需時間很可能長於調用getc,因為調用函數通常所需的時間長於調用宏。

  首先說第一點應該怎麼理解呢,這個是因為宏這個東西坑蠻多,這裡舉個經典的例子。

  

   在這個程序中,z2我想算8*8,但是傳入的參數是5+3,6+2,宏替換之後就變成了5+3*6+2,最後結果就成了25。

  那麼第二點又是什麼意思呢,這個其實就是一個函數指針,一個函數的地址能夠傳遞給一個函數指針,讓其來調用,但是宏就不行了!比如說下面這段代碼:

  

  由於MAX是個宏,所以就不能賦值給函數指針了!

  關於第三點,這就涉及到一點匯編的知識了,在匯編語言中,函數的調用是通過棧來實現的!就是調用的時候壓棧,調用完了再彈棧(關於匯編我也不是很清楚,所以敘述的有點粗糙,還望見諒!),比如下面這段代碼:

 1 #include<stdio.h>
 2 void func3()
 3 {
 4     printf("Hello,World!");
 5 }
 6 void func2()
 7 {
 8     func3();
 9 }
10 void func1()
11 {
12     func2();
13 }
14 int main(int argc,char *argv[])
15 {
16     func1();
17     return 0;
18 }

  我用gdb調試,在第4行設置了一個斷點,查看它的函數調用棧如下:

  

  而通過宏調用是不用壓棧的,所以getc的速度就比fgetc快那麼一點。

  不過,關於這個是有一點例外,就是有時候調用函數並不是通過棧來實現的,所以作者用了一個很可能的詞匯。關於這個問題,這個帖子講的非常好(fgetc和getc,哪個速度快?)。

 

  OK,上面就是fgetc和getc的不同了!不過需要補充一點的是關於GNU C下這兩個函數其實是一樣的,他們都是通過函數來實現的,然後getc再簡單粗暴地增加了一個宏的聲明。具體如下:

  在stdio.h這個文件中getc的聲明是這樣的:

  

  而在libio.h裡面那個_IO_getc (_fp)這個函數的聲明又是這樣的:

  

  

  所以,最後,各位親們,我想說的是,不要再糾結了,這兩個函數敞開了用吧,區別不是很大,一般不會出啥問題的!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved