舉個簡單的例子!你會容易理解的。
你寫一個stack.h的頭文件,裏面聲明幾個函數原形:
stack.h
#ifndef STACK_H
#define STACK_H
extern void push(char);
extern char pop(void);
extern int is_empty(void);
#endif
你能夠在其相應的stack.c中對這些函數進行實現
stack.c
#include "stack.h"
void push(char)
{
/*your code*/
}
char pop(void)
{
/*your code*/
}
int is_empty(void)
{
/*your code*/
}
在main.c中你能夠這樣寫
#include <stdio.h>
#include "stack.h"
int main()
{
push('a');
push('b');
push('c');
while(!is_empty())
putchar(pop());
putchar('\n');
return 0;
}
大體格式就是這樣,在stack.h(這個名字你能夠隨便定),在這個頭文件中聲明函數原形,在相應的stack.c中進行函數定義與實現,主程序文件中包含這個頭文件以後就能夠調用stack.h中聲明的函數,編譯後無錯誤便可執行,程序員
在咱們語言的初學階段,每每咱們的程序只有一個.c的文件或這不多的幾個,這時咱們就不多遇到頭文件組織這個頭疼的問題,隨着咱們程序的增長,代碼 量到了幾千行甚至幾萬行,文件數也愈來愈多。這時這些文件的組織就成了一個問題,其實說白了這些文件的組織問題從理論上來講是軟件工程中的模塊設計等等的問題。函數
由上能夠看出,.h文件最初就是用來給變量和函數提供一些全局性的聲明,這些聲明被其餘.c文件共享,方便變量和聲明的修改,使得大型代碼邏輯更清晰更易於維護。所以.h文件中通常是聲明,不多有代碼的具體實現。那麼爲何在.h文件中實現函數也不會出錯呢?在.h文件中實現函數與在.c文件中實現函數有什麼區別和聯繫呢?普通的.C文件和包含main函數的c文件有什麼區別和聯繫呢?編碼
要解決上述問題,首先必須弄清編譯器的工做原理。編譯器的最終目的是將程序員編寫的源代碼轉換成機器可以識別運行的二進制機器碼。大致上分,能夠分爲4個步驟:翻譯
1.頭文件的預編譯,預處理設計
編譯器在編譯源代碼時,會先編譯頭文件,保證每一個頭文件只被編譯一次。3d
在預處理階段,編譯器將c文件中引用的頭文件中的內容所有寫到c文件中。code
2.詞法和語法分析(查錯)get
3.編譯(彙編代碼)編譯器
轉化爲彙編碼,這種文件稱爲目標文件。io
4.連接(二進制機器碼)
將彙編代碼轉換爲機器碼,生成可執行文件。
在編譯過程當中,.h文件中的全部內容會被寫到包含它的.c文件中,而全部的.c文件以一個共同的main函數做爲可執行程序的入口。所以,在.h文件中編寫函數實現並不會出錯,至關於全部.h的內容最後都被寫到了main.c文件中。可是爲了邏輯性、易於維護性以及一些其餘目的(可參考c語言中.h文件和.c文件的解析 ),通常在.h文件中寫函數的聲明,在.c文件中編寫函數的實現。
預編譯
僞指令特殊符號處理
編譯
默認獲得二進制 ,可是按步驟是獲得彙編代碼。
彙編
把彙編代碼翻譯成機器碼 。一般把編譯和彙編合成一個編譯 ,將通過預處理後的源文件經過編譯獲得機器碼 ,目標文件
連接
將多個庫文件,目標文件對接 ,生成可執行文件
聲明:本文中如出現侵權文字,請留言