一個簡單的問題:.c和.h文件的區別
學了幾個月的C語言,反而覺得越來越不懂了。同樣是子程序,可以定義在.c文件中,也可以定義在.h文件中,那這兩個文件到底在用法上有什麼區別呢?
2樓:
子程序不要定義在.h中。
函數定義要放在.c中,而.h只做聲明.否則多引用幾次,就會發生函數重復定義的錯誤。
3樓:
.h只做聲明,編譯後不產生代碼
4樓:
這樣做目的是為了實現軟件的模塊化
使軟件結構清晰,而且也便於別人使用你寫的程序
純粹用 C 語言語法的角度,你當然可以在 .h 中放任何東西,因為 #include 完全等價 於把 .h 文件 Ctrl-C Ctrl-V 到 .c 中
.h 中應該都是一些宏定義和變量、函數聲明,告訴別人你的程序“能干什麼、該怎麼用”
.c 中是所有變量和函數的定義,告訴計算機你的程序“該怎麼實現”
5樓:
當然,如果一個 .h 被多個 .c 包含
而且 .h 中有對象(變量或函數)的定義,就會發生重復定義的錯誤了
聲明可以無窮多次,定義只能一次
6樓:
一般來說,一個C文件應該是一個模塊
如果你的程序僅僅有一個模塊(僅僅一個C文件),就可以不用建立H文件了。
否則你的模塊肯定不是獨立的,你的模塊裡面的實現要被別的模塊調用。這個時候你最好生成一個頭文件(H文件),在頭文件裡面可以聲明你的那些函數是公共的。當別的模塊包含你的頭文件後,就可以使用你的公共聲明了。
7樓:
一個C對應一個H,這樣管理起來方便
比如你有一個"feed_dog.c",那麼就再添加一個"feed_dog.h":
#ifndef _feed_dog_h
#define _feed_dog_h
extern void feed_dog(void);
#endif
其實在H文件裡寫函數也無所謂,只是不符合習慣而已。只要按照以上的格式寫,一個H文件添加多少次都無所謂,呵呵
8樓:
只是一種約定
在編譯器裡面,.c和.h是沒有區別的,.c和.h如何使用完全取決於程序員,不過為了你的程序以後還能看懂而且別人也能看懂,請遵守普遍的約定,這些約定前面的大蝦們已經講了很多了.
這個就象汽車在馬路上要靠右行使一樣,是人為約定,汽車(編譯器)本身並不知道自己是在靠左還是靠右行使.
如果你喜歡,還可以用任意後綴命名源文件和頭文件,但這樣干可能會導致集成編譯和調試環境罷工,你只好自己寫makefile文件了.
9樓:
非常感謝各位大俠,不過我現在越來越糊塗了
1,當一個函數要經常使用(比如有十幾個C文件使用它)時,一般我都放在H文件裡,並在前面加上__inline.對於__inline函數,很多C文件都可以INCLUDE這個H文件,但是它好象只能被一個H文件INCLUDE,如果有兩個H文件INCLUDE它,就會出現編譯錯誤。
2,有些數組變量,其大小可能達十幾K,而且要賦初值,這就不放在C文件裡了,要不人都蒙了。
3,
#ifndef _feed_dog_h
#define _feed_dog_h
extern void feed_dog(void);
#endif
mohanwei兄,是不是這樣定議了,這個feed_dog.h就可以無數次的被INCLUDE了?
11樓:
#ifndef _feed_dog_h //如果到目前為止還沒有定義過“_feed_dog_h”這個宏
#define _feed_dog_h //則定義“_feed_dog_h”這個宏
extern void feed_dog(void); //聲明一個外部函數
#endif //“#ifndef”到此結束
所以,不管你定義多少次(哪怕你在同一個C文件裡定義多次),都不會發生沖突的。
在網上看到一篇關於.H和.C的文章,感覺不錯,帖出與大家共享.
簡單的說
其實要理解C文件與頭文件有什麼不同之處,首先需要弄明白編譯器的工作過程,一般說來編譯器會做以下幾個過程:
1.預處理階段
2.詞法與語法分析階段
3.編譯階段,首先編譯成純匯編語句,再將之匯編成跟CPU相關的二進制碼,生成各個目標文件
4.連接階段,將各個目標文件中的各段代碼進行絕對地址定位,生成跟特定平台相關的可執行文件,當然,最後還可以用objcopy生成純二進制
碼,也就是去掉了文件格式信息.
編譯器在編譯時是以C文件為單位進行的,也就是說如果你的項目中一個C文件都沒有,那麼你的項目將無法編譯,連接器是以目標文件為單位
,它將一個或多個目標文件進行函數與變量的重定位,生成最終的可執行文件,在PC上的程序開發,一般都有一個main函數,這是各個編譯器
的約定,當然,你如果自己寫連接器腳本的話,可以不用main函數作為程序入口!!!!
有了這些基礎知識,再言歸正傳,為了生成一個最終的可執行文件,就需要一些目標文件,也就是需要C文件,而這些C文件中又需要一個main
函數作為可執行程序的入口,那麼我們就從一個C文件入手,假定這個C文件內容如下:
#include <stdio.h>
#include "mytest.h"
int main(int argc,char **argv)
{
test = 25;
printf("test.................%d\n",test);
}
頭文件內容如下:
int test;
現在以這個例子來講解編譯器的工作:
1.預處理階段:編譯器以C文件作為一個單元,首先讀這個C文件,發現第一句與第二句是包含一個頭文件,就會在所有搜索路徑中尋找這兩個
文件,找到之後,就會將相應頭文件中再去處理宏,變量,函數聲明,嵌套的頭文件包含等,檢測依賴關系,進行宏替換,看是否有重復定義
與聲明的情況發生,最後將那些文件中所有的東東全部掃描進這個當前的C文件中,形成一個中間“C文件”
2.編譯階段,在上一步中相當於將那個頭文件中的test變量掃描進了一個中間C文件,那麼test變量就變成了這個文件中的一個全局變量,此時
就將所有這個中間C文件的所有變量,函數分配空間,將各個函數編譯成二進制碼,按照特定目標文件格式生成目標文件,在這種格式的目標文
件中進行各個全局變量,函數的符號描述,將這些二進制碼按照一定的標准組織成一個目標文件