C語言中的.h頭文件的作用

      網友投稿 1241 2025-03-31

      首先C語言是一門面向過程的編程語言,它是由一系列的函數組成的。函數的使用必須遵守:

      先聲明后使用的原則

      舉個例子說明一下,下面是一個test.c的源程序:

      #include int main(){ sayHello(); return 0; } void sayHello(){ printf("Tom says:%s\n","Hello!"); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      我們在terminal上用gcc編譯一下這個程序:

      ~$ gcc test.c -o test

      1

      然后就報了如下的錯誤:

      test.c: In function ‘main’: test.c:4:2: warning: implicit declaration of function ‘sayHello’; did you mean ‘ftello’? [-Wimplicit-function-declaration] sayHello(); ^~~~~~~~ ftello test.c: At top level: test.c:7:6: warning: conflicting types for ‘sayHello’ void sayHello(){ ^~~~~~~~ test.c:4:2: note: previous implicit declaration of ‘sayHello’ was here sayHello(); ^~~~~~~~

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      正確的做法是在調用sayHello()函數前,先聲明這個函數。這里解釋一下,為什么在函數調用前需要先聲明,這主要是由編譯器的編譯過程決定的:

      編譯器看到了一個不認識的函數調用:sayHello()函數。編譯器此時不會報錯,它認為在該源文件后面會找到這個函數的詳細信息,所以它記錄下這個函數,隨后會在文件中查找函數。

      編譯器需要知道函數的返回類型,因此在它記錄下這個函數后,它會假設它返回int。

      等到編譯器看到實際函數時,發現返回的不是int,而是void,所以它就會報出“conflicting types for ‘sayHello’的錯誤,就是說函數的返回類型沖突了。如果sayHello的返回值是int,它就不會報錯了,頂多給個警告。如果在調用前,就進行了函數聲明,那么編譯器在函數調用的地方就可以清楚地知道函數的返回類型,它就不用自己假設成int了,也就不會有后面的錯誤了,而這種假設通常很危險。這就是為什么在函數調用前必須先聲明的原因。

      test.c的完整且正確的程序如下。

      下面這種是在源文件開頭添加函數聲明:

      #include void sayHello(); //函數聲明 int main(){ sayHello(); return 0; } void sayHello(){ printf("Tom says:%s\n","Hello!"); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      C語言中的.h頭文件的作用

      11

      或是下面這種調整main函數與sayHello函數的位置:

      #include void sayHello(){ printf("Tom says:%s\n","Hello!"); } int main(){ sayHello(); return 0; }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      再次編譯運行,就完全沒有問題了:

      ~$ gcc test.c -o test ~$ ./test Tom says:Hello!

      1

      2

      3

      補充:運行目標程序時要加上./,為什么呢?因為在類Unix系統上,必須指定可執行文件所在的目錄,除非目錄已添加到PATH環境變量中。./表示當前目錄下。

      其中調整函數的順序其實是一件很痛苦的事情,尤其在加入新入的函數的時候,特別容易出現上述錯誤。如果寫一些相互遞歸調用的函數,它們互相調用對方,那么總有一個函數在定義 前被調用了,那如何是好?有沒有一種方法既不用調整代碼,又能讓編譯器知道函數返回類型呢?有,將函數聲明都寫在源文件的開頭或用頭文件的形式將聲明與定義進行分離。我們來說說用頭文件的方式。

      將函數聲明放在一個.h的頭文件中,然后再把.h文件包含進來就可以了。

      函數聲明只是一個函數簽名,一條包含函數名、形參類型、返回類型的記錄。我們將上述函數的聲明放到一個叫tong.h的頭文件中去:

      void sayHello();

      1

      在test.c引入tong.h頭文件

      #include #include "tong.h" //引入頭文件 int main(){ sayHello(); return 0; } void sayHello(){ printf("Tom says:%s\n","Hello!"); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      這樣一來,編譯器在一開始就知道函數的返回類型,就不用稍后再找了,而且防止了編譯器假設函數的返回類型,可以顯式地告訴它了。這種告訴編譯器函數會返回什么類型的語句就叫函數聲明。如果代碼中有很多函數,而你又不想管它們在文件中的順序,那么可以在源文件開頭列出函數聲明,甚至可以把這些函數聲明放到一個頭文件中,再通過include指令包含進來。

      小知識:

      頭文件的名稱用雙引號括起來和用尖括號括起來的區別:

      1.用雙引號括起來的文件名,編譯器就會在本地查找文件,如果是加上了目錄的文件名,編譯器就會在相對路徑下查找頭文件;

      2.用尖括號括起來的文件名,編譯器就會在標準庫里找,gcc知道在哪里。在類Unix系統中,頭文件一般都放在/usr/local/include 、/usr/include這些地方。

      以上談到的頭文件作用是為了能夠調整函數之間的順序,以下將介紹的頭文件作用是為了讓其他程序知道某個函數,從而達到共享這個函數的目的:

      例如我們要共享如下這個加密函數,那么我們需要想辦法讓其他程序知道它,這時就可以用頭文件了:

      void encrypt(char *message){ while(*message){ *message = *message ^ 31; message++; } }

      1

      2

      3

      4

      5

      6

      1.創建一個encrypt.h的頭文件:

      void encrypt(char *message);

      1

      2.在encrypt.c中包含這個頭文件,這樣可以讓其他程序知道encrypt()函數:

      #include "encrypt.h" void encrypt(char *message){ while(*message){ *message = *message ^ 31; message++; } }

      1

      2

      3

      4

      5

      6

      7

      3.在test1.c程序中使用這個函數,只需要包含這個頭文件就可以了:

      #include #include "encrypt.h" int main(){ char c[] = "hello world"; encrypt(c); printf("%s\n",c); return 0; }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      這樣一來在主程序test1.c引入了encrypt.h,編譯器就可以知道encrypt()函數,這樣才能編譯代碼。最后,為了把所有東西編譯到一起,只需要把源文件都傳給gcc:

      ~$ gcc test1.c encrypt.c -o testEncrypt ~$ ./testEncrypt wzssp?hpms{

      1

      2

      3

      這樣把加密程序放到了一個單獨文件中,就可以在任何程序中使用它了。

      至此.h頭文件的第二個作用也講完了,謝謝大家的支持。

      C 語言

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:自動化可以改善現場服務管理的4種方法
      下一篇:快速顯示銷售額的波動趨勢的excel數據處理方法(銷量增長率怎么算Excel)
      相關文章
      亚洲短视频男人的影院| 国产AV无码专区亚洲精品| 亚洲av无码专区在线播放| 亚洲国产黄在线观看| 国产精品成人亚洲| 香蕉视频亚洲一级| 亚洲av日韩aⅴ无码色老头 | 亚洲熟妇无码AV在线播放| 久99精品视频在线观看婷亚洲片国产一区一级在线 | 亚洲精品自产拍在线观看| 国产亚洲av片在线观看18女人| 亚洲国产香蕉人人爽成AV片久久| 国产亚洲视频在线观看网址| 国产精品亚洲专区无码不卡| 亚洲成人一区二区| 亚洲国产精品综合久久一线| 亚洲精品无码久久不卡| 亚洲中文字幕伊人久久无码| 国产黄色一级毛片亚洲黄片大全| JLZZJLZZ亚洲乱熟无码| 亚洲午夜久久久久久久久久| 亚洲国产美女精品久久久久∴| 亚洲午夜国产精品无码老牛影视 | 亚洲av无码片在线观看| 亚洲精品免费网站| 亚洲第一街区偷拍街拍| 无码不卡亚洲成?人片| 亚洲国产天堂久久综合| 国产精品亚洲mnbav网站 | 亚洲成a人片在线看| 亚洲中文字幕AV每天更新| 亚洲av永久中文无码精品| 国产成人高清亚洲一区久久| 亚洲男人在线无码视频| 亚洲精品乱码久久久久久自慰| 亚洲精品国产成人99久久| 亚洲欧洲久久精品| 亚洲无人区码一二三码区别图片 | 日韩精品亚洲人成在线观看| 亚洲伊人色一综合网| 亚洲色偷偷综合亚洲AV伊人蜜桃|