首先,你對#include會發生什麼感到困惑。你永遠不會「編譯」標準庫。標準庫已經被編譯並且位於庫文件中(Windows上的.dll和.lib文件,Linux上的.a和.so)。 #include所做的是將聲明所需的鏈接提供給標準庫。
理解#include指令的第一步是它們非常低級。如果您使用Java或Python進行編程,#includes與導入有很大不同。進口在較高級別上告訴編譯器「這個源文件需要使用這個包」,編譯器會指出如何解決這個依賴。 C指令中的#include指出:「在編譯時,將此文件的全部內容直接粘貼到這裏。」特別是,#include <stdio.h>
引入了一個文件,該文件具有標準庫中所有I/O函數的前向聲明。然後,編譯代碼時,編譯器知道如何調用這些函數並檢查它們的類型是否正確。
一旦你的程序被編譯,它是鏈接到標準庫。這意味着您的鏈接器(由您的編譯器自動調用)將導致您的可執行文件使用共享標準庫(.dll或.so),或者將複製靜態標準庫(.lib或.a)到您的可執行文件中。在任何情況下,您的可執行文件都不會「包含」您不使用的標準庫的任何部分。
至於創建一個庫,這是一個複雜的話題,我會把它留給別人,特別是因爲我不認爲這是你真正想要根據你的問題的下一部分做什麼。
頭文件並不總是庫的一部分。看來你擁有的是多個源文件,並且你希望能夠使用另一個源文件中的源文件中的函數。你可以做到這一點,而無需創建一個庫。你需要做的就是把聲明作爲foo.c,你想從其他地方訪問到foo.h中。聲明就像函數原型和「extern」變量聲明一樣。例如,如果foo.c中包含
int some_global;
void some_function(int a, char b)
{
/* Do some computation */
}
然後,爲了使這些從其他源文件,foo.h中需要包含
extern int some_global;
void some_function(int, char);
然後訪問,你#include "foo.h"
無論你想使用some_global或some_function。由於標題可以包含其他標題,因此通常會將標題封裝在「包含標題」中,以便不重複聲明。例如,foo.h中真的應該讀:
#ifndef FOO_H
#define FOO_H
extern int some_global;
void some_function(int, char);
#endif
這意味着該標題將僅每編譯單元(源文件)一旦被處理。
至於如何編譯它們,切勿將.h文件放在編譯器命令行上,因爲它們不應該包含任何可編譯的代碼(只有聲明)。在大多數情況下,是完全沒有編譯爲
cc main.c 1.c 2.c 3.c ... [etc]
不過,如果你有50個源文件,它可能是方便多了,如果你使用的編譯系統。在Linux上,這是一個Makefile。在Windows上,它取決於你使用的開發環境。你可以谷歌的,或者一旦你指定你的平臺問另一個SO問題(因爲這個問題已經很廣泛了)。
構建系統的優點之一是它們獨立地編譯每個源文件,然後將它們全部鏈接在一起,以便當只更改一個源文件時,只需要重新編譯該文件(並且程序重新鏈接),而不是重新編譯所有內容,包括沒有更改的內容。當程序變大時,這會造成很大的時間差。
您使用的平臺是?如果Windows我建議建立一個靜態庫或DLL,從外部代碼可以鏈接到這些靜態庫或DLL,但這些都是特定於Windows的 – 2009-08-27 10:27:48