面試所遇問題

2021-08-27 03:19:06 字數 3971 閱讀 8077

一. python中元組合列表有什麼區別?

python 的元組與列表類似,不同之處在於元組的元素不能修改,元組中的元素不能被刪除。

元組使用小括號,列表使用方括號。

二. c++中友元函式的作用?

友元函式提供了不同類或物件的成員函式之間、類的成員函式和一般函式之間進行資料共享的機制。通俗的說,友元關係就是乙個類主動宣告哪些類或函式是它的朋友,進而給它們提供對本類的訪問特性。也就是說,通過友元關係,乙個普通函式或者類的成員函式可以訪問封裝於另外乙個類中的資料。

友元函式是在類中用關鍵字friend修飾的非成員函式,可以是乙個普通的函式,或是其它類的成員函式。雖然它不是本類的成員函式,卻在它的函式體中卻可以通過物件名訪問類的私有成員和保護成員。

同友元函式一樣,乙個類可以將另乙個類宣告為友元類。若a類為b類的友元函類,則a類中的所有成員函式都是b類的友元函式,都可以訪問b類的私有和保護成員。

三. c語言中指標和陣列有什麼區別?

在c語言中,指標和陣列名都表示位址,但兩者卻有很大的不同之處。

首先,舉個簡單的例子:

char *p1="hello!";  //定義字元型指標p1,並將指標p1指向字串「hello!」的首位址。

char s[10]="hello!";  //定義陣列s,並將其初始化賦值。

然而,如果char s[10]; s="hello!";這樣就會報錯,為什麼呢?原因很簡單,因為陣列名是常量。

言歸正傳,現在舉兩個簡單的例子:

例子1void main()

char p="abcdef";

p[0]='y';

printf("%s",p);

在本段程式中輸出ybcdef

例子2void main()

char *p="abcdef";

p[0]='y';

printf("%s",p);

本段程式卻丟擲異常,為什麼?

在例子2中,char *p="abcdef",指標p是儲存在堆疊區,但字串是常量,儲存在常量區,只是指標p指向了儲存在常量區的字串首位址,此時不能改變常量區的字串的值。

在例子1中,char p="abcdef",此處的賦值是將常量區的字串「abcdef」拷貝到了堆疊區的陣列p的空間了。陣列p是在堆疊區開闢了空間,此時是可以修改字串的值,因為修改的是堆疊區的字串的值。另外此時的陣列名p是堆疊區中的」abcdef「的首位址。

對於堆疊區和常量區的區別,還需要了解一下記憶體區域的劃分和分配問題。

1.記憶體分配方式

c語言中記憶體分配方式有三種:

[1]從靜態儲存區域分配。內存在程式編譯的時候就已經分配好,這塊內存在程式的整個執行期間都存在。例如全域性變數,static變數。

[2]在上建立。在執行函式時,函式內區域性變數的儲存單元都可以在棧上建立,函式執行結束時這些儲存單元自動被釋放。棧記憶體分配運算內置於處理器的指令集中,效率很高,但是分配的記憶體容量有限。

[3]從上分配,亦稱動態記憶體分配。程式在執行的時候用malloc或new申請任意多少的記憶體,程式設計師自己負責在何時用free或delete釋放記憶體。動態記憶體的生存期由程式設計師決定,使用非常靈活,但如果在堆上分配了空間,就有責任**它,否則執行的程式會出現記憶體洩漏,頻繁地分配和釋放不同大小的堆空間將會產生堆內碎塊。

乙個由c/c++編譯的程式占用的記憶體分為以下幾個部分

1、棧區(stack)—程式執行時由編譯器自動分配,存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。程式結束時由編譯器自動釋放。

2、堆區(heap)— 在記憶體開闢另一塊儲存區域。一般由程式設計師分配釋放, 若程式設計師不釋放,程式結束時可能由os** 。注意它與資料結構中的堆是兩回事,分配方式倒是類似於鍊錶,呵呵。用malloc, calloc, realloc等分配記憶體的函式分配得到的就是在堆上

3、全域性區(靜態區)(static)—編譯器編譯時即分配記憶體。全域性變數和靜態變數的儲存是放在一塊的。對於c語言初始化的全域性變數和靜態變數在一塊區域, 未初始化的全域性變數和未初始化的靜態變數在相鄰的另一塊區域。而c++則沒有這個區別 - 程式結束後由系統釋放

4、文字常量區—常量字串就是放在這裡的。 程式結束後由系統釋放

5、程式**區—存放函式體的二進位制**。

例子程式:

int a = 0; 全域性初始化區

char *p1; 全域性未初始化區

main()

3.堆與棧的比較

3.1申請方式

stack: 由系統自動分配。 例如,宣告在函式中乙個區域性變數 int b; 系統自動在棧中為b開闢空間。

heap: 需要程式設計師自己申請,並指明大小,在c中malloc函式,c++中是new運算子

如p1 = (char *)malloc(10); p1 = new char[10];

如p2 = (char *)malloc(10); p2 = new char[20];

但是注意p1、p2本身是在棧中的。

3.2申請後系統的響應

棧:只要棧的剩餘空間大於所申請空間,系統將為程式提供記憶體,否則將報異常提示棧溢位。

堆:首先應該知道作業系統有乙個記錄空閒記憶體位址的鍊錶,當系統收到程式的申請時,會遍歷該鍊錶,尋找第乙個空間大於所申請空間的堆結點,然後將該結點從空閒結點鍊錶中刪除,並將該結點的空間分配給程式。

對於大多數系統,會在這塊記憶體空間中的首位址處記錄本次分配的大小,這樣,**中的delete語句才能正確的釋放本記憶體空間。

由於找到的堆結點的大小不一定正好等於申請的大小,系統會自動的將多餘的那部分重新放入空閒鍊錶中。

3.3申請大小的限制

棧:在windows下,棧是向低位址擴充套件的資料結構,是一塊連續的記憶體的區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,在 windows下,棧的大小是2m(也有的說是1m,總之是乙個編譯時就確定的常數),如果申請的空間超過棧的剩餘空間時,將提示overflow。因 此,能從棧獲得的空間較小。

堆:堆是向高位址擴充套件的資料結構,是不連續的記憶體區域。這是由於系統是用鍊錶來儲存的空閒記憶體位址的,自然是不連續的,而鍊錶的遍歷方向是由低位址向高位址。堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。

3.4申請效率的比較

棧由系統自動分配,速度較快。但程式設計師是無法控制的。

堆是由new分配的記憶體,一般速度比較慢,而且容易產生記憶體碎片,不過用起來最方便。

另外,在windows下,最好的方式是用virtualalloc分配記憶體,他不是在堆,也不是棧,而是直接在程序的位址空間中保留一快記憶體,雖然用起來最不方便。但是速度快,也最靈活。

3.5堆和棧中的儲存內容

棧:在函式呼叫時,第乙個進棧的是主函式中後的下一條指令(函式呼叫語句的下一條可執行語句)的位址,然後是函式的各個引數,在大多數的c編譯器中,引數是由右往左入棧的,然後是函式中的區域性變數。注意靜態變數是不入棧的。

當本次函式呼叫結束後,區域性變數先出棧,然後是引數,最後棧頂指標指向最開始存的位址,也就是主函式中的下一條指令,程式由該點繼續執行。

堆:一般是在堆的頭部用乙個位元組存放堆的大小。堆中的具體內容有程式設計師安排。

3.6訪問效率的比較

char s1 = "a";

char *s2 = "b";

a是在執行時刻賦值的;而b是在編譯時就確定的;但是,在以後的訪問中,在棧上的陣列比指標所指向的字串(例如堆)快。 

參考:    感謝作者

參考:       感謝作者

工作所遇問題總結

入職後,單位給看的第乙個專案 是mfc程式,裡面利用cwintread類來生成乙個工作執行緒,而這個執行緒是可以接收訊息的,這讓我感覺很驚奇,居然還有這樣的技術?這個執行緒可以接收訊息,也可以利用postthreadmessage給主線程傳送訊息,真是讓我感覺新奇。我一定要弄明白,其中的道理!軟體狗...

Python學習所遇問題

print 遊戲開始 num input 猜數字 guess int num while guess 8 num input 猜錯啦請重新輸入 guess int num if guess 8 print 恭喜你猜對了 else if guess 8 print 偏大 else print 偏小 p...

TD專案所遇問題

1.之前為了顯示人物模型在ui中,所以將canvas的render mode改為screen space camera,但這個時候在伺服器選擇頁面出現了content下的伺服器按鈕全部放大了5倍左右,未解決此問題。暫定解決方法 在指令碼中讓每個按鈕固定大小為1倍 2.粒子系統所遇到的問題 匯入了舊版...