360-c++開發(fā)面經(jīng)(三)
點(diǎn)擊藍(lán)字關(guān)注我們,獲取更多面經(jīng)



一、限制符號的作用域只在本程序文件
若變量或函數(shù)(統(tǒng)稱符號)使用static修飾,則只能在本程序文件內(nèi)使用,其他程序文件不能調(diào)用(非static的可以通過extern 關(guān)鍵字聲明該變量是在其他文件內(nèi)定義的,此文件可調(diào)用)。不加static修飾的,則默認(rèn)是可以被其他程序文件調(diào)用的。
本程序文件內(nèi)的非static函數(shù)也可以隨意調(diào)用static的變量和函數(shù)。只是限制了外部程序文件的函數(shù)不能調(diào)用。
原理:默認(rèn)的變量和函數(shù)名(統(tǒng)一稱為符號)在編譯成匯編代碼.s文件時(shí),會有.globl func_name,.globl指示告訴匯編器,func_name這個(gè)符號要被鏈接器用到(匯編文件在經(jīng)過匯編器處理成二進(jìn)制的.o文件時(shí),符號會被變量或函數(shù)實(shí)際的地址值代替),所以要在目標(biāo)文件的符號表中標(biāo)記它是一個(gè)全局符號。如果一個(gè)符號沒有用.globl聲明,就表示這個(gè)符號不會被鏈接器用到。而static關(guān)鍵字修飾的符號在編譯成匯編代碼.s文件時(shí),就不會被.globl聲明,因此不會參與后序鏈接就不會被其他程序文件調(diào)用到。
(不同程序文件的函數(shù)變量互相調(diào)用是在鏈接各個(gè).o文件步驟后進(jìn)行的,前面預(yù)編譯、編譯、匯編步驟都是對單個(gè)程序文件進(jìn)行操作)
二、指定變量的存儲位置
對于函數(shù)內(nèi)的變量。auto變量(函數(shù)局部變量)都是在棧內(nèi)存區(qū)存放,函數(shù)結(jié)束后就自動(dòng)釋放。但是全局的和函數(shù)內(nèi)定義的static變量都是存放在數(shù)據(jù)區(qū)的,且只存一份,只在整個(gè)程序結(jié)束后才自動(dòng)釋放。
由于static變量只存一份即同一地址,所以不管函數(shù)調(diào)用多少次,函數(shù)內(nèi)定義static變量的語句只會在第一次調(diào)用時(shí)執(zhí)行,后面調(diào)用都不執(zhí)行也不再初始化,而是對該地址內(nèi)的數(shù)據(jù)進(jìn)行操作。
三、C++類的靜態(tài)成員變量
是屬于類,而不屬于某個(gè)實(shí)例對象,因此也只有一個(gè)地址保存一份數(shù)據(jù)存放于數(shù)據(jù)區(qū)。在類中只是聲明,并不是定義,因此不分配內(nèi)存,對類用sizeof求大小也不會將static變量得大小加入。
必須在類聲明的外部,以及main()函數(shù)的外部,也就是全部變量區(qū)域?qū)︻惖膕tatic成員變量再次定義(定以后才分配唯一內(nèi)存,此時(shí)該類靜態(tài)成員變量相當(dāng)于是全局的靜態(tài)變量了,只是調(diào)用的時(shí)候要使用類名加::)。若只定義不賦值初始化,則默認(rèn)初始化為0。
public的靜態(tài)數(shù)據(jù)成員既可以通過類名引用,也可以通過對象名引用(會自動(dòng)轉(zhuǎn)換成類名引用)。
四、C++類的靜態(tài)成員函數(shù)
只能調(diào)用本類的靜態(tài)成員變量或函數(shù),不能調(diào)用本類的非靜態(tài)成員函數(shù)和變量。因?yàn)榉庆o態(tài)成員函數(shù)和變量在類成員函數(shù)中調(diào)用時(shí),都是由形參中隱含一個(gè)指向當(dāng)前實(shí)例對象的this指針來調(diào)用。然而靜態(tài)成員函數(shù)沒有這個(gè)this形參。


一個(gè)空類含有的函數(shù):
class Empty{};// 等價(jià)于class Empty{public:Empty(){ //默認(rèn)構(gòu)造函數(shù)}Empty(const Empty& rhs){ //拷貝構(gòu)造函數(shù)}~Empty(){ //析構(gòu)函數(shù)}Empty& operator=(const Empty rhs){ //重載賦值操作符函數(shù)}Empty* operator & (); // 取址運(yùn)算符const Empty* operator & () const; // 取址運(yùn)算符const};
這些函數(shù)只有在被調(diào)用的時(shí)候才會被編譯器創(chuàng)建出來。
Empty e1; // 默認(rèn)構(gòu)造函數(shù)
Empty e2(e1); // 拷貝構(gòu)造函數(shù)
e2 = e1; //重載賦值操作符
拷貝構(gòu)造函數(shù)和重載賦值操作符函數(shù)用于將來源對象的每一個(gè)非靜態(tài)成員變量拷貝到目標(biāo)對象。
如果類中含有指針型的數(shù)據(jù)成員、需要使用動(dòng)態(tài)內(nèi)存,程序員最好顯式定義自己的復(fù)制構(gòu)造函數(shù),避免各種可能出現(xiàn)的內(nèi)存錯(cuò)誤。
默認(rèn)的拷貝構(gòu)造函數(shù)是淺拷貝,可能導(dǎo)致兩個(gè)指針指向了堆里的同一個(gè)空間,在銷毀對象時(shí),兩個(gè)對象的析構(gòu)函數(shù)將對同一個(gè)內(nèi)存空間釋放兩次,從而引發(fā)錯(cuò)誤。
對于對象中動(dòng)態(tài)成員,就不能簡單賦值,而應(yīng)該重新動(dòng)態(tài)分配空間。
class Rect{public:Rect() // 構(gòu)造函數(shù),p指向堆中分配的一空間{p = new int(100);}Rect(const Rect& r){width = r.width;height = r.height;p = new int; // 為新對象重新動(dòng)態(tài)分配空間*p = *(r.p);}~Rect() // 析構(gòu)函數(shù),釋放動(dòng)態(tài)分配的空間{if(p != NULL){delete p;}}private:int width;int height;int *p; // 一指針成員};


數(shù)組:
數(shù)組是將元素在內(nèi)存中連續(xù)存放,由于每個(gè)元素占用內(nèi)存 相同,可以通過下標(biāo)迅速訪問數(shù)組中任何元素。但是如果要在數(shù)組中增加一個(gè)元素,需要移動(dòng)大量元素,在內(nèi)存中空出一個(gè)元素的空間,然后將要增加的元素放在其 中。同樣的道理,如果想刪除一個(gè)元素,同樣需要移動(dòng)大量元素去填掉被移動(dòng)的元素。如果應(yīng)用需要快速訪問數(shù)據(jù),很少或不插入和刪除元素,就應(yīng)該用數(shù)組。
鏈表:
鏈表恰好相反,鏈表中的元素在內(nèi)存中不是順序存儲的,而是通過存在元素中的指針聯(lián)系到一起。比如:上一個(gè)元素有個(gè)指針指到下一個(gè)元素,以此類推,直到最后 一個(gè)元素。如果要訪問鏈表中一個(gè)元素,需要從第一個(gè)元素開始,一直找到需要的元素位置。但是增加和刪除一個(gè)元素對于鏈表數(shù)據(jù)結(jié)構(gòu)就非常簡單了,只要修改元 素中的指針就可以了。如果應(yīng)用需要經(jīng)常插入和刪除元素你就需要用鏈表數(shù)據(jù)結(jié)構(gòu)了。
C++語言中可以用數(shù)組處理一組數(shù)據(jù)類型相同的數(shù)據(jù), 但不允許動(dòng)態(tài)定義數(shù)組的大小,即在使用數(shù)組之前必須確定數(shù)組的大小。而在實(shí)際應(yīng)用中,用戶使用數(shù)組之前有時(shí)無法準(zhǔn)確確定數(shù)組的大小,只能將數(shù)組定義成足夠 大小,這樣數(shù)組中有些空間可能不被使用,從而造成內(nèi)存空間的浪費(fèi)。鏈表是一種常見的數(shù)據(jù)組織形式,它采用動(dòng)態(tài)分配內(nèi)存的形式實(shí)現(xiàn)。需要時(shí)可以用new分配 內(nèi)存空間,不需要時(shí)用delete將已分配的空間釋放,不會造成內(nèi)存空間的浪費(fèi)。
(1) 從邏輯結(jié)構(gòu)角度來看
a, 數(shù)組必須事先定義固定的長度(元素個(gè)數(shù)),不能適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況。當(dāng)數(shù)據(jù)增加時(shí),可能超出原先定義的元素個(gè)數(shù);當(dāng)數(shù)據(jù)減少時(shí),造成內(nèi)存浪費(fèi)。
b,鏈表動(dòng)態(tài)地進(jìn)行存儲分配,可以適應(yīng)數(shù)據(jù)動(dòng)態(tài)地增減的情況,且可以方便地插入、刪除數(shù)據(jù)項(xiàng)。(數(shù)組中插入、刪除數(shù)據(jù)項(xiàng)時(shí),需要移動(dòng)其它數(shù)據(jù)項(xiàng))
(2)從內(nèi)存存儲角度來看
a,(靜態(tài))數(shù)組從棧中分配空間, 對于程序員方便快速,但自由度小。
b, 鏈表從堆中分配空間, 自由度大但申請管理比較麻煩.
數(shù)組和鏈表的區(qū)別整理如下:
數(shù)組靜態(tài)分配內(nèi)存,鏈表動(dòng)態(tài)分配內(nèi)存;
數(shù)組在內(nèi)存中連續(xù),鏈表不連續(xù);
數(shù)組元素在棧區(qū),鏈表元素在堆區(qū);
數(shù)組利用下標(biāo)定位,時(shí)間復(fù)雜度為O(1),鏈表定位元素時(shí)間復(fù)雜度O(n);
數(shù)組插入或刪除元素的時(shí)間復(fù)雜度O(n),鏈表的時(shí)間復(fù)雜度O(1)。
更多面經(jīng)
掃描二維碼
獲取更多面經(jīng)
扶搖就業(yè)
