C++深入理解(1)------計算機編譯過程

    這是第二遍讀C++ Primer Plus這本書,對C++的認識有了進一步的瞭解,關於計算機對代碼的編譯過程有了進一步的瞭解,這裏寫出來作爲自己的筆記。

    代碼的編譯過程大致分爲以下幾個步驟:預處理-編譯-鏈接-生成。

    說下對這句話總得理解:在編寫代碼時,總會有.h和.c文件,實際上編譯的過程是將.c文件轉化爲目標文件(計算機可以識別的文件,一般都以.o文件作爲後綴),進一步在將所有的目標文件進行鏈接形成一個可執行文件。

    預處理的過程在淺層上的理解就是執行#等文件,而從實際原理上來說,是將每一個.c文件的代碼的#部分找出來,然後進行預處理的過程:這個過程是將#後邊的內容解析出來,如文件包含#include <iostream> 就是將iostream文件的內容放在.c文件的開頭,經過所有的替換之後,就相當於東風也具備了,就可以真正的解析.c文件了。

    在構建代碼的時候,要考慮到每一個.c文件都是一個相對獨立的個體,用到外部的東西,都應該用#預處理語句包含進來。這裏會涉及到自己寫.h文件的幾個注意事項:

    (1).自己寫.h文件一定要防止重複包含。可以使用#ifndef #define 或者使用#pragma once等。

    (2).儘量不要在.h文件中包含其他文件,而是在對應.c文件中包含需要的文件,這樣可以減少程序的複雜度,更好理解

    (3)..h文件一定不可以用來定義變量,只可以聲明,否則就會編譯錯誤

    (4)..h文件中儘量不要使用過於複雜的類或者模板作爲參數,如string,就會產生warning,雖然可以關閉warning,但是強迫症表示函數有些不舒服。

    然後就可以將文件轉換爲目標文件,接下來的步驟是鏈接的過程,就是將所有的.o目標文件轉化爲一個可執行文件,但是這個過程如果遇到重複定義等的問題就會報錯,或者無法找到對應的依賴庫。所以在涉及的過程中就要注意變量的定義,防止出現錯誤。

    在進行鏈接之前,編譯器需要對函數進行適當的處理,這樣鏈接程序才能認識函數,實現真正的鏈接程序的效果,那麼在底層編譯器是如何處理這些函數,使其可以成爲被鏈接程序認識的語言呢?

    在C++中,一般講函數轉成_函數名_參數類型名_參數類型名,如int add(int a,double b),會被轉化爲_add_i_d,這種轉化被稱爲C++的語言鏈接性。但是在C語言中並不是這樣操作的,會被轉化爲_add形式,所以兩種是完全不同的編譯形式,但是時長會出現這樣的情況,例如在C++的程序中必須使用C函數庫,如lua的函數庫,所以必須使用C的編譯形式,系統才能正常找到函數,進行正常的鏈接工作。

    一般使用如下方式聲明編譯的方式:

extern "C" void add();    //根據C語言的規則
void add();               //根據C++的規則
extern "C++" void add();  //根據C++的規則



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章