c源文件中為什么要包含自己對應的頭文件


另一篇:.c文件和.h文件的關系  

引言:

            我們經常在c工程中發現,源文件中要包含自己的頭文件。一直以來,都不知道為什么這樣做。現在,我知道了。

以前的認知:

 我認為,.c文件沒有必要包含自己的.h文件。.h文件包含.c文件中定義的函數和全局變量的聲明,.h文件就是.c文件提供的對外接口文件。既然.h文件就是.c文件提供的對外接口文件,那么.c文件就沒必要包含自己的.h文件了(.h文件是對外提供用的,對內又何必再包含進來呢)。

          鑒於這樣的理解,我對於工程中.c源文件包含自己的.h頭文件很是不理解,不知道為什么要這樣做。

現在對此的理解:

          但是現在,我知道為什么要源文件包含自己的頭文件了。

如下,一段書中的原話:

“如果希望讓編譯器檢查聲明的一致性,一定要把全局聲明放到頭文件中。特別是,永遠不要把外部函數的原型(也就是函數聲明)放到.c文件中:通常它與定義的一致性不能得到檢查,而矛盾的原型(也就是函數聲明)比不用還糟糕。”

注意:外部函數的原型,就是外部函數的聲明。

對這段話的理解:

      為什么:“永遠不要把外部函數的原型放到.c 文件中”

這個外部函數A指的是B.c文件之外定義的函數,B.c文件中需要使用外部函數A,就需要先對外部函數A聲明(對外部函數的聲明就是外部函數原型)。對這個外部函數A的聲明,不能放在B.c文件里面來實現。

以實例說明:

①假若工程中有2個源文件a.c和b.c;a.c的頭文件為a.h,b.c的頭文件為b.h。

②a.c中定義了一個函數sum。

③b.c要引用sum這個函數。做法是:在b.c中聲明sum這個函數。然后b.c就可以使用sum函數了。

這樣的做法就是把外部函數sum的聲明放到了b.c中來。然而,這樣的做法很不妥。

不妥的原因:

sum是在a.c中定義的,而聲明確是在b.c中,sum函數的定義和聲明不是在同一個文件中的。定義和聲明不在同一個文件中,編譯的時候,編譯器就不能對定義和聲明的一致性進行檢查。這樣,如果sum的定義和聲明不一致,編譯器就無法檢查出來(定義和聲明不在同一個文件中),那么編譯的時候不會報錯,但是程序運行的時候就可能會出錯。而這樣的錯誤,查找起來又不是很容易。

鑒於此,才這樣說:“永遠不要把外部函數的原型放到.c文件中”。

那如何才能讓編譯器檢查定義和聲明的一致性呢?

前面說,如果把外部函數的原型放到.c文件中,編譯器就無法檢查聲明和定義的一致性(聲明和定義不在同一個文件中)。那么,要讓編譯器檢查定義和聲明的一致性呢,自然是把定義和聲明放在同一個文件中,而如何實現把定義和聲明放在同一個文件里呢?

答案:源文件定義的函數,在源文件對應的頭文件中聲明,然后源文件包含自己的頭文件。這樣定義和聲明就放在同一個文件里了。

 

 

 

援引上述例子:a.c中定義了函數sum,而函數本質上是外部的,函數sum是可以被其它源文件調用的。那么,我們把sum函數的聲明放在a.h中。然后a.c源文件還要包含自己的頭文件,也就是a.h文件。而b.c文件要引用sum函數,就直接包含a.h文件就可以。

sum函數的定義在a.c中,聲明是在a.h中,但是由於a.c包含了a.h,所以sum的定義和聲明就是在同一個文件a.c中了。這樣,編譯器編譯的時候,就能對sum函數定義和聲明的一致性做檢查,如果不一致,就會報錯。

至於其他源文件引用這個外部函數sum,不再采用直接聲明的方式,而是通過包含a.h頭文件的方式。

這樣,編譯器檢查了sum函數定義和聲明的一致性沒有報錯,也就表明a.c中sum函數的定義和a.h中sum函數的聲明是一致的。那么其他源文件都是通過直接包含a.h,來使用函數sum,就也保證了sum函數聲明和定義的一致性了。

結論

c源文件要包含自己的頭文件,目的就是讓編譯器檢查定義和聲明的一致性。

 

轉自:https://blog.csdn.net/khwkhwkhw/article/details/49798985

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM