海康威視C++開發(fā)
C++源碼到可執(zhí)行程序的過程
https://www.cnblogs.com/smile233/p/8423015.html
這篇博客講的太詳細(xì)了,我覺得實際可以精簡為:
源代碼-->預(yù)處理-->編譯-->匯編-->鏈接-->可執(zhí)行文件
預(yù)處理
(1)宏定義指令,如#define Name TokenString,#undef等。對于前一個偽指令,預(yù)編譯所要做的是將程序中的所有Name用TokenString替換,但作為字符串常量的Name則不被替換。對于后者,則將取消對某個宏的定義,使以后該串的出現(xiàn)不再被替換。
(2)條件編譯指令,如#ifdef,#ifndef,#else,#elif,#endif,等等。這些偽指令的引入使得程序員可以通過定義不同的宏來決定編譯程序?qū)δ男┐a進行處理。預(yù)編譯程序?qū)⒏鶕?jù)有關(guān)的文件,將那些不必要的代碼過濾掉
(3)頭文件包含指令,如#include "FileName"或者#include <FileName>等。在頭文件中一般用偽指令#define定義了大量的宏(最常見的是字符常量),同時包含有各種外部符號的聲明。采用頭文件的目的主要是為了使某些定義可以供多個不同的C源程序使用。因為在需要用到這些定義的C源程序中,只需加上一條#include語句即可,而不必再在此文件中將這些定義重復(fù)一遍。預(yù)編譯程序?qū)杨^文件中的定義統(tǒng)統(tǒng)都加入到它所產(chǎn)生的輸出文件中,以供編譯程序?qū)χM行處理。
包含到c源程序中的頭文件可以是系統(tǒng)提供的,這些頭文件一般被放在/usr/include目錄下。在程序中#include它們要使用尖括號。(<>)。另外開發(fā)人員也可以定義自己的頭文件,這些文件一般與c源程序放在同一目錄下,此時在#include中要用雙引號("")。
(4)特殊符號,預(yù)編譯程序可以識別一些特殊的符號。例如在源程序中出現(xiàn)的LINE標(biāo)識將被解釋為當(dāng)前行號(十進制數(shù)),F(xiàn)ILE則被解釋為當(dāng)前被編譯的C源程序的名稱。預(yù)編譯程序?qū)τ谠谠闯绦蛑谐霈F(xiàn)的這些串將用合適的值進行替換。編譯
編譯過程就是把預(yù)處理完的文件進行一系列的詞法分析,語法分析,語義分析及優(yōu)化后生成相應(yīng)的匯編代碼。經(jīng)過預(yù)編譯得到的輸出文件中,將只有常量。如數(shù)字、字符串、變量的定義,以及C語言的關(guān)鍵字,如main,if,else,for,while,{,},+,-,*,\,等等。編譯程序所要作得工作就是通過詞法分析和語法分析,在確認(rèn)所有的指令都符合語法規(guī)則之后,將其翻譯成等價的中間代碼表示或匯編代碼。匯編
匯編過程實際上指把匯編語言代碼翻譯成目標(biāo)機器指令的過程。對于被翻譯系統(tǒng)處理的每一個C語言源程序,都將最終經(jīng)過這一處理而得到相應(yīng)的目標(biāo)文件。目標(biāo)文件中所存放的也就是與源程序等效的目標(biāo)的機器語言代碼。鏈接
由匯編程序生成的目標(biāo)文件并不能立即就被執(zhí)行,其中可能還有許多沒有解決的問題。例如,某個源文件中的函數(shù)可能引用了另一個源文件中定義的某個符號(如變量或者函數(shù)調(diào)用等);在程序中可能調(diào)用了某個庫文件中的函數(shù),等等。所有的這些問題,都需要經(jīng)鏈接程序的處理方能得以解決。
通過調(diào)用鏈接器ld來鏈接程序運行需要的一大堆目標(biāo)文件,以及所依賴的其它庫文件,最后生成可執(zhí)行文件。
函數(shù)重載 變量前有無const是否可以重載
https://www.cnblogs.com/qingergege/p/7609533.html
- fun(int i) 和 fun(const int i),不能重載
二者是一樣的,是因為函數(shù)調(diào)用中存在實參和形參的結(jié)合。假如我們用的實參是int a,那么這兩個函數(shù)都不會改變a的值,這兩個函數(shù)對于a來說是沒有任何區(qū)別的,所以不能通過編譯,提示重定義。 - fun(char *a) 和 fun(const char *a),可以重載
因為char *a 中a指向的是一個字符串變量,而const char *a指向的是一個字符串常量,所以當(dāng)參數(shù)為字符串常量時,調(diào)用第二個函數(shù),而當(dāng)函數(shù)是字符串變量時,調(diào)用第一個函數(shù)。 - char *a和char * const a,不能重載
這兩個都是指向字符串變量,不同的是char *a是指針變量 而char *const a是指針常量,這就和int i和const int i的關(guān)系一樣了,所以也會提示重定義。 - 對于引用,比如int &i 和const int & i 也是可以重載的,原因是第一個i引用的是一個變量,而第二個i引用的是一個常量,兩者是不一樣的,類似于上面的指向變量的指針的指向常量的指針。
全局變量,靜態(tài)全局變量可以被其他文件調(diào)用么,為什么
https://blog.csdn.net/candyliuxj/article/details/7853938
https://www.cnblogs.com/invisible2/p/6905892.html
- 全局變量
在a.h中聲明全局變量:extern int a; 一般需要加上extern,否則編譯器可能默認(rèn)給一個初始化值。那樣會導(dǎo)致多個cpp文件在包含此頭文件時發(fā)生重復(fù)定義。
在a.cpp文件中定義全局變量:int a =10;
在b.cpp中想要使用這個全局變量,有兩種方法,第一種是使用extern關(guān)鍵字,例如extern int a; 代表當(dāng)前變量a 的定義來自于其他文件,當(dāng)進行編譯時,會去其他文件里面找。且在當(dāng)前文件僅做聲明,而不是重新定義一個新的變量。第二種方法是使用include "a.h",這種方法的好處是a里面的方法可以直接拿過來使用。
extern作用
作用一:當(dāng)它與"C"一起連用時,如extern "C" void fun(int a, int b);,則編譯器在編譯fun這個函數(shù)名時按C的規(guī)則去翻譯相應(yīng)的函數(shù)名而不是C++的。
作用二:當(dāng)它不與"C"在一起修飾變量或函數(shù)時,如在頭文件中,extern int g_nNum;,它的作用就是聲明函數(shù)或變量的作用范圍的關(guān)鍵字,其聲明的函數(shù)和變量可以在本編譯單元或其他編譯單元中使用。 - 靜態(tài)全局變量(static)
注意使用static修飾變量,就不能使用extern來修飾,即static和extern不可同時出現(xiàn)。 static修飾的全局變量的聲明與定義同時進行,即當(dāng)你在頭文件中使用static聲明了全局變量,同時它也被定義了。
static修飾的全局變量的作用域只能是本身的編譯單元。在其他編譯單元使用它時,只是簡單的把其值復(fù)制給了其他編譯單元,其他編譯單元會另外開個內(nèi)存保存它,在其他編譯單元對它的修改并不影響本身在定義時的值。即在其他編譯單元A使用它時,它所在的物理地址,和其他編譯單元B使用它時,它所在的物理地址不一樣,A和B對它所做的修改都不能傳遞給對方。
多個地方引用靜態(tài)全局變量所在的頭文件,不會出現(xiàn)重定義錯誤,因為在每個編譯單元都對它開辟了額外的空間進行存儲。
TCP什么情況會重傳
https://www.cnblogs.com/virusolf/p/4335613.html
發(fā)端計時器超時
快重傳