[英]Why do we need to include the C or CPP declaration files during compilation and not the default libraries like iostream?
如果需要使用我們自己的帶有聲明的頭文件和帶有定義的cpp文件來編譯C
或CPP
程序,我們需要在編譯命令中包含帶有定義的cpp文件(請參閱此答案 )。 但是,當我們編寫#include <iostream>
,我們不會在編譯語句中包含iostream.cpp
,如g++ main.cpp iostream.cpp -o main
。
如果我們寫我們的報關文件,例如hello.hpp
帶班宣言和hello.cpp
與定義,我們需要使用編譯它g++ main.cpp hello.cpp -o main
包括后hello.hpp
在頭main.cpp
文件。 為什么是這樣?
編輯 :我們可以模仿我們的自定義頭文件和cpp文件的標准模板庫的行為,這樣我們所要做的就是包含頭文件並自動編譯聲明嗎? 如果是,那怎么樣? 如果不是,為什么不呢?
標准庫正在隱式鏈接。 所以
g++ main.cpp -o main
是真的
g++ main.cpp -o main -lstdc++ -lc
其中libstdc++
是c ++標准庫, libc
是c標准庫。 其他庫需要明確鏈接(例如libm
)。
如果您將編譯和鏈接步驟分開,這將變得更加清晰:
g++ -c main.cpp -o main.o
g++ -c other.cpp -o other.o
g++ main.o other.o /usr/lib/libstdc++.a /usr/lib/libc.a -o main
這里我們將main()
函數定義和其他定義( other.cpp
)編譯成目標文件,並將它們與標准庫中現有的編譯函數/類/變量定義相結合。
首先,檢查在這篇文章中包含<filename>
和"filename"
之間的區別:
對於#include“filename”,預處理器在與包含該指令的文件相同的目錄中進行搜索。 此方法通常用於包括程序員定義的頭文件。
對於#include <filename>,預處理器以依賴於實現的方式搜索,通常在編譯器/ IDE預先指定的搜索目錄中搜索。 此方法通常用於包括標准庫頭文件
您包含文件的事實並不意味着您正在編譯文件。 事實上,通過包含你正在解決包含文件的語法引用,如類聲明(在C ++中),常見變量,結構,枚舉和函數調用。 這將避免代碼獲取未引用的對象錯誤,從而破壞編譯過程。
使用這些引用編譯代碼並不意味着編譯原始引用的代碼。 舉個例子:
mycode.cpp
包含myclass.hpp
,如下所示:
#include "myclass.hpp"
如果引用正確,您可以使用以下命令編譯它:
g++ mycode.cpp
你將有一個mycode.cpp
(一個名為mycode.o
的目標文件)的編譯代碼,但不是myclass
的編譯代碼。 mycode.cpp
編譯正確,因為它有對myclass
對象/函數/等的引用,但這並不意味着myclass
被編譯(你還沒有一個對象文件myclass.o
)。
如果你鏈接編輯mycode.cpp
,將會有幾個缺少的引用,因為沒有myclass
編譯代碼。
如果您選擇:
g++ mycode.cpp myclass.cpp
它將為mycode.o
和myclass.o
生成目標文件,以后可以將它們鏈接在一起。
對於STL庫,您只需要引用,因為它們已經編譯並且可用於所謂的標准庫(已經為您編譯的一組對象.o
文件)。 如果您正確地告訴他這樣做,那么liker會自動聯系在一起。
我建議你通過compilation -> object files -> link editing -> executable file
進程來理解這些步驟,這只發生在編譯語言中。
您需要了解編譯器讀取輸入文件,然后預處理它們,預處理器替換所有#include語句,以便編譯器本身永遠不會看到它們。 就真正的編譯器而言,沒有#include語句。 然后,編譯器將源語言轉換為機器代碼。 編譯器為每個輸入(c或cpp)文件編寫一個目標文件。 目標文件中的機器碼不能直接執行; 它必須與其他代碼鏈接。
最初,程序員會將程序與已經編譯成目標文件庫的其他目標文件鏈接起來。 多個目標文件靜態鏈接在一起以生成可執行文件,並且可以對許多可執行文件執行此操作。 換句話說,許多目標文件中的每一個都可能存在多次,對於許多可執行文件中的每一個都存在一次。 這意味着當某些內容發生變化時,有時必須再次鏈接許多使用相同目標文件的程序。 后來的程序員了解到它有助於動態鏈接到目標文件,這就是動態鏈接庫。
編譯程序時,編譯器包含鏈接器鏈接到其他庫的指令,主要是“C運行時”(CRT)。 鏈接可以是靜態鏈接或動態鏈接。 此外,標頭提供有關CRT的信息。 大多數標准庫(std命名空間)實際上都在標題中,例如在“iostream”中,並使用您的程序進行編譯。 標題中沒有的任何內容都在某個CRT庫中。
因此,iostream.cpp的等價物可能在您自己的程序中,例如main.cpp,或者已經編譯過,並且位於與您的程序鏈接的CRT庫中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.