50個C語言C++常見面試題及答案_第1頁
50個C語言C++常見面試題及答案_第2頁
50個C語言C++常見面試題及答案_第3頁
50個C語言C++常見面試題及答案_第4頁
50個C語言C++常見面試題及答案_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、 c/c+經(jīng)典面試題 面試題 1:變量的聲明和定義有什么區(qū)別 為變量分配地址和存儲空間的稱為定義,不分配地址的稱為聲明。一個變量可以在多個地方聲明,但是只在一個地方定義。加入 extern 修飾的是變量的聲明,說明此變量將在文件以外或在文件后面部分定義。 說明:很多時候一個變量,只是聲明不分配內(nèi)存空間,直到具體使用時才初始化,分配內(nèi)存空間,如外部變量。 面試題 2:寫出 bool 、int、 float、指針變量與“零值”比較的 if 語句 bool 型數(shù)據(jù): if( flag ) a; else b; int 型數(shù)據(jù): if( 0 != flag ) a; else b; 指針型數(shù): if(

2、 null = flag ) a; else b; float 型數(shù)據(jù): if ( ( flag = norm ) & ( flag = norm ) ) a; 2 注意:應(yīng)特別注意在 int、指針型變量和“零值”比較的時候,把“零值”放在左邊,這樣當把“=”誤寫成“=”時,編譯器可以報錯,否則這種邏輯錯誤不容易發(fā)現(xiàn),并且可能導致很嚴重的后果。 面試題 3:sizeof 和 strlen 的區(qū)別 sizeof 和 strlen 有以下區(qū)別: sizeof 是一個操作符,strlen 是庫函數(shù)。 sizeof 的參數(shù)可以是數(shù)據(jù)的類型,也可以是變量,而 strlen 只能以結(jié)尾為0的字符串

3、作參數(shù)。 編譯器在編譯時就計算出了 sizeof 的結(jié)果。而 strlen 函數(shù)必須在運行時才能計算出來。并且 sizeof計算的是數(shù)據(jù)類型占內(nèi)存的大小,而 strlen 計算的是字符串實際的長度。 數(shù)組做 sizeof 的參數(shù)不退化,傳遞給 strlen 就退化為指針了。 注意:有些是操作符看起來像是函數(shù),而有些函數(shù)名看起來又像操作符,這類容易混淆的名稱一定要加以區(qū)分,否則遇到數(shù)組名這類特殊數(shù)據(jù)類型作參數(shù)時就很容易出錯。最容易混淆為函數(shù)的操作符就是 sizeof。 面試題 4:c 語言的關(guān)鍵字 static 和 c+ 的關(guān)鍵字 static 有什么區(qū)別 在 c 中 static 用來修飾局部

4、靜態(tài)變量和外部靜態(tài)變量、函數(shù)。而 c+中除了上述功能外,還用來定義類的成員變量和函數(shù)。即靜態(tài)成員和靜態(tài)成員函數(shù)。 注意:編程時 static 的記憶性,和全局性的特點可以讓在不同時期調(diào)用的函數(shù)進行通信,傳遞信息,而 c+的靜態(tài)成員則可以在多個對象實例間進行通信,傳遞信息。 面試題 5:中的 malloc 和中的 new 有什么區(qū)別 malloc 和 new 有以下不同: (1)new、delete 是操作符,可以重載,只能在 c+中使用。 (2)malloc、free 是函數(shù),可以覆蓋,c、c+中都可以使用。 (3)new 可以調(diào)用對象的構(gòu)造函數(shù),對應(yīng)的 delete 調(diào)用相應(yīng)的析構(gòu)函數(shù)。 (

5、4)malloc 僅僅分配內(nèi)存,free 僅僅回收內(nèi)存,并不執(zhí)行構(gòu)造和析構(gòu)函數(shù) (5)new、delete 返回的是某種數(shù)據(jù)類型指針,malloc、free 返回的是 void 指針。 注意:malloc 申請的內(nèi)存空間要用 free 釋放,而 new 申請的內(nèi)存空間要用 delete 釋放,不要混用。因為兩者實現(xiàn)的機理不同。 面試題 6:寫一個“標準”宏 min #define min(a,b)(a)=(b)?(a):(b) 注意:在調(diào)用時一定要注意這個宏定義的副作用,如下調(diào)用: (+*p)=(x)?(+*p):(x)。 p 指針就自加了兩次,違背了 min 的本意。 3 面試題 7:一個指

6、針可以是 volatile 嗎 可以,因為指針和普通變量一樣,有時也有變化程序的不可控性。常見例:子中斷服務(wù)子程序修改一個指向一個 buffer 的指針時,必須用 volatile 來修飾這個指針。 說明:指針是一種普通的變量,從訪問上沒有什么不同于其他變量的特性。其保存的數(shù)值是個整型數(shù)據(jù),和整型變量不同的是,這個整型數(shù)據(jù)指向的是一段內(nèi)存地址。 面試題 8:a 和&a 有什么區(qū)別 請寫出以下代碼的打印結(jié)果,主要目的是考察 a 和&a 的區(qū)別。 #include void main( void ) int a5=1,2,3,4,5; int *ptr=(int *)(&a

7、+1); printf(%d,%d,*(a+1),*(ptr-1); return; 輸出結(jié)果:2,5。 注意:數(shù)組名 a 可以作數(shù)組的首地址,而&a 是數(shù)組的指針。思考,將原式的 int *ptr=(int *)(&a+1);改為 int *ptr=(int *)(a+1);時輸出結(jié)果將是什么呢? 面試題 9:簡述 c、c+程序編譯的內(nèi)存分配情況 c、c+中內(nèi)存分配方式可以分為三種: (1)從靜態(tài)存儲區(qū)域分配: 內(nèi)存在程序編譯時就已經(jīng)分配好,這塊內(nèi)存在程序的整個運行期間都存在。速度快、不容易出錯,因為有系統(tǒng)會善后。例如全局變量,static 變量等。 (2)在棧上分配: 在執(zhí)

8、行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。棧內(nèi)存分配運算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。 (3)從堆上分配: 即動態(tài)內(nèi)存分配。程序在運行的時候用 malloc 或 new 申請任意大小的內(nèi)存,程序員自己負責在何時用 free 或 delete 釋放內(nèi)存。動態(tài)內(nèi)存的生存期由程序員決定, 使用非常靈活。如果在堆上分配了空間,就有責任回收它,否則運行的程序會出現(xiàn)內(nèi)存泄漏,另外頻繁地分配和釋放不同大小的堆空間將會產(chǎn)生堆內(nèi)碎塊。 一個 c、c+程序編譯時內(nèi)存分為 5 大存儲區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)、程序代碼區(qū)。 4 面試題

9、10:簡述 strcpy、sprintf 與 memcpy 的區(qū)別 三者主要有以下不同之處: (1) 操作對象不同, strcpy 的兩個操作對象均為字符串,sprintf 的操作源對象可以是多種數(shù)據(jù)類型,目的操作對象是字符串, memcpy 的兩個對象就是兩個任意可操作的內(nèi)存地址, 并不限于何種數(shù)據(jù)類型。 (2)執(zhí)行效率不同,memcpy 最高,strcpy 次之,sprintf 的效率最低。 (3)實現(xiàn)功能不同,strcpy 主要實現(xiàn)字符串變量間的拷貝,sprintf 主要實現(xiàn)其他數(shù)據(jù)類型格式到字符串的轉(zhuǎn)化,memcpy 主要是內(nèi)存塊間的拷貝。 說明:strcpy、sprintf 與 me

10、mcpy都可以實現(xiàn)拷貝的功能,但是針對的對象不同,根據(jù)實際需求,來選擇合適的函數(shù)實現(xiàn)拷貝功能。 面試題 11:設(shè)置地址為 0 x67a9 的整型變量的值為 0 xaa66 int *ptr; ptr = (int *)0 x67a9; *ptr = 0 xaa66; 說明: 這道題就是強制類型轉(zhuǎn)換的典型例子, 無論在什么平臺地址長度和整型數(shù)據(jù)的長度是一樣的,即一個整型數(shù)據(jù)可以強制轉(zhuǎn)換成地址指針類型,只要有意義即可。 面試題 12:面向?qū)ο蟮娜筇卣?面向?qū)ο蟮娜筇卣魇欠庋b性、繼承性和多態(tài)性: 封裝性:將客觀事物抽象成類,每個類對自身的數(shù)據(jù)和方法實行 protection(private, p

11、rotected,public)。 繼承性:廣義的繼承有三種實現(xiàn)形式:實現(xiàn)繼承(使用基類的屬性和方法而無需額外編碼的能力)、可視繼承(子窗體使用父窗體的外觀和實現(xiàn)代碼)、接口繼承(僅使用屬性和方法,實現(xiàn)滯后到子類實現(xiàn))。 多態(tài)性:是將父類對象設(shè)置成為和一個或更多它的子對象相等的技術(shù)。用子類對象給父類對象賦值之后,父類對象就可以根據(jù)當前賦值給它的子對象的特性以不同的方式運作。 說明:面向?qū)ο蟮娜齻€特征是實現(xiàn)面向?qū)ο蠹夹g(shù)的關(guān)鍵,每一個特征的相關(guān)技術(shù)都非常的復(fù)雜,程序員應(yīng)該多看、多練。 面試題 13:c+的空類有哪些成員函數(shù) 缺省構(gòu)造函數(shù)。 缺省拷貝構(gòu)造函數(shù)。 缺省析構(gòu)函數(shù)。 缺省賦值運算符。 缺省

12、取址運算符。 缺省取址運算符 const。 注意:有些書上只是簡單的介紹了前四個函數(shù)。沒有提及后面這兩個函數(shù)。但后面這兩個函數(shù)也是空類的默認函數(shù)。另外需要注意的是,只有當實際使用這些函數(shù)的時候,編譯器才會去定義它們。 5 面試題 14:談?wù)勀銓截悩?gòu)造函數(shù)和賦值運算符的認識 拷貝構(gòu)造函數(shù)和賦值運算符重載有以下兩個不同之處: (1)拷貝構(gòu)造函數(shù)生成新的類對象,而賦值運算符不能。 (2)由于拷貝構(gòu)造函數(shù)是直接構(gòu)造一個新的類對象,所以在初始化這個對象之前不用檢驗源對象是否和新建對象相同。而賦值運算符則需要這個操作,另外賦值運算中如果原來的對象中有內(nèi)存分配要先把內(nèi)存釋放掉 注意:當有類中有指針類型的成

13、員變量時,一定要重寫拷貝構(gòu)造函數(shù)和賦值運算符,不要使用默認的。 面試題 15:用 c+設(shè)計一個不能被繼承的類 template class a friend t; private: a() a() ; class b : virtual public a public: b() b() ; class c : virtual public b public: c() c() ; void main( void ) b b; /c c; return; 注意:構(gòu)造函數(shù)是繼承實現(xiàn)的關(guān)鍵,每次子類對象構(gòu)造時,首先調(diào)用的是父類的構(gòu)造函數(shù),然后才是自己的。 面試題 16:訪問基類的私有虛函數(shù) 寫出以下程

14、序的輸出結(jié)果: #include class a 6 virtual void g() cout a:g endl; private: virtual void f() cout a:f endl; ; class b : public a void g() cout b:g endl; virtual void h() cout b:h endl; ; typedef void( *fun )( void ); void main() b b; fun pfun; for(int i = 0 ; i next; /記錄上次翻轉(zhuǎn)后的鏈表 oldlist- next = newhead; /將當

15、前結(jié)點插入到翻轉(zhuǎn)后鏈表的開頭 newhead = oldlist; /遞歸處理剩余的鏈表 return ( next=null )? newhead: reverse( t, newhead ); 說明:循環(huán)算法就是圖 10.2圖 10.5 的移動過程,比較好理解和想到。遞歸算法的設(shè)計雖有一點難度,但是理解了循環(huán)算法,再設(shè)計遞歸算法就簡單多了。 面試題 21:簡述隊列和棧的異同 隊列和棧都是線性存儲結(jié)構(gòu),但是兩者的插入和刪除數(shù)據(jù)的操作不同,隊列是“先進先出”,棧是“后進先出”。 注意:區(qū)別棧區(qū)和堆區(qū)。堆區(qū)的存取是“順序隨意”,而棧區(qū)是“后進先出”。棧由編譯器自動分配釋放 ,存放函數(shù)的參數(shù)值,局

16、部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。堆一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由 os 回收。分配方式類似于鏈表。 它與本題中的堆和棧是兩回事。 堆棧只是一種數(shù)據(jù)結(jié)構(gòu), 而堆區(qū)和棧區(qū)是程序的不同內(nèi)存存儲區(qū)域。 面試題 22:能否用兩個棧實現(xiàn)一個隊列的功能 結(jié)點結(jié)構(gòu)體: typedef struct node int data; node *next; node,*linkstack; 創(chuàng)建空棧: linkstack createnullstack( linkstack &s) s = (linkstack)malloc( sizeof( node ) ); /申

17、請新結(jié)點 if( null = s) printf(fail to malloc a new node.n); 9 return null; s-data = 0; /初始化新結(jié)點 s-next = null; return s; 棧的插入函數(shù): linkstack push( linkstack &s, int data) if( null = s) /檢驗棧 printf(there no node in stack!); return null; linkstack p = null; p = (linkstack)malloc( sizeof( node ) ); /申請新結(jié)點

18、 if( null = p) printf(fail to malloc a new node.n); return s; if( null = s-next) p-next = null; else p-next = s-next; p-data = data; /初始化新結(jié)點 s-next = p; /插入新結(jié)點 return s; 出棧函數(shù): node pop( linkstack &s) node temp; temp.data = 0; temp.next = null; if( null = s) /檢驗棧 printf(there no node in stack!);

19、return temp; temp = *s; 10 if( s-next = null ) printf(the stack is null,cant pop!n); return temp; linkstack p = s -next; /節(jié)點出棧 s-next = s-next-next; temp = *p; free( p ); p = null; return temp; 雙棧實現(xiàn)隊列的入隊函數(shù): linkstack stacktoqueupush( linkstack &s, int data) node n; linkstack s1 = null; createnul

20、lstack( s1 ); /創(chuàng)建空棧 while( null != s-next ) /s 出棧入 s1 n = pop( s ); push( s1, n.data ); push( s1, data ); /新結(jié)點入棧 while( null != s1-next ) /s1 出棧入 s n = pop( s1 ); push( s, n.data ); return s; 說明:用兩個棧能夠?qū)崿F(xiàn)一個隊列的功能,那用兩個隊列能否實現(xiàn)一個隊列的功能呢?結(jié)果是否定的,因為棧是先進后出,將兩個棧連在一起,就是先進先出。而隊列是現(xiàn)先進先出,無論多少個連在一起都是先進先出,而無法實現(xiàn)先進后出。 面

21、試題 23:計算一顆二叉樹的深度 深度的計算函數(shù): int depth(bitree t) if(!t) return 0; /判斷當前結(jié)點是否為葉子結(jié)點 11 int d1= depth(t-lchild); /求當前結(jié)點的左孩子樹的深度 int d2= depth(t-rchild); /求當前結(jié)點的右孩子樹的深度 return (d1d2?d1:d2)+1; 注意:根據(jù)二叉樹的結(jié)構(gòu)特點,很多算法都可以用遞歸算法來實現(xiàn)。 面試題 24:編碼實現(xiàn)直接插入排序 直接插入排序編程實現(xiàn)如下: #include void main( void ) int array10 = 0, 6, 3, 2,

22、7, 5, 4, 9, 1, 8 ; int i,j; for( i = 0; i 10; i+) coutarrayi ; coutendl; for( i = 2; i = 10; i+ ) /將 array2,arrayn依次按序插入 if(arrayi arrayi-1) /如果 arrayi大于一切有序的數(shù)值, /arrayi將保持原位不動 array0 = arrayi; /將 array0看做是哨兵,是 arrayi的副本 j = i - 1; do /從右向左在有序區(qū) array1i-1中 /查找 arrayi的插入位置 arrayj+1 = arrayj; /將數(shù)值大于 ar

23、rayi記錄后移 j- ; while( array0 arrayj ); arrayj+1=array0; /arrayi插入到正確的位置上 for( i = 0; i 10; i+) coutarrayi ; coutendl; 12 注意:所有為簡化邊界條件而引入的附加結(jié)點(元素)均可稱為哨兵。引入哨兵后使得查找循環(huán)條件的時間大約減少了一半,對于記錄數(shù)較大的文件節(jié)約的時間就相當可觀。類似于排序這樣使用頻率非常高的算法,要盡可能地減少其運行時間。所以不能把上述算法中的哨兵視為雕蟲小技。 面試題 25:編碼實現(xiàn)冒泡排序 冒泡排序編程實現(xiàn)如下: #include #define len 10

24、/數(shù)組長度 void main( void ) int array10 = 0, 6, 3, 2, 7, 5, 4, 9, 1, 8 ; /待排序數(shù)組 printf( n ); for( int a = 0; a len; a+ ) /打印數(shù)組內(nèi)容 printf( %d , arraya ); int i = 0; int j = 0; bool ischange; /設(shè)定交換標志 for( i = 1; i = i; j- ) /對當前無序區(qū) arrayi.len自下向上掃描 if( arrayj+1 arrayj ) /交換記錄 array0 = arrayj+1; /array0不是哨兵

25、,僅做暫存單元 arrayj+1 = arrayj; arrayj = array0; ischange = 1; /發(fā)生了交換,故將交換標志置為真 printf( n ); for( a = 0; a len; a+) /打印本次排序后數(shù)組內(nèi)容 printf( %d , arraya ); if( !ischange ) /本趟排序未發(fā)生交換,提前終止算法 break; printf( n ); return; 13 面試題 26:編碼實現(xiàn)直接選擇排序 #includestdio.h #define len 9 void main( void ) int arraylen= 5, 6, 8,

26、 2, 4, 1, 9, 3, 7 ; /待序數(shù)組 printf(before sorted:n); for( int m = 0; m len; m+ ) /打印排序前數(shù)組 printf( %d , arraym ); for (int i = 1; i = len - 1; i+) /選擇排序 int t = i - 1; int temp = 0; for (int j = i; j len; j+) if (arrayj arrayt) t = j; if (t != (i - 1) temp = arrayi - 1; arrayi - 1 = arrayt; arrayt = te

27、mp; printf( n ); printf(after sorted:n); for( i = 0; i len; i+ ) /打印排序后數(shù)組 printf( %d , arrayi ); printf( n ); 注意:在直接選擇排序中,具有相同關(guān)鍵碼的對象可能會顛倒次序,因而直接選擇排序算法是一種不穩(wěn)定的排序方法。在本例中只是例舉了簡單的整形數(shù)組排序,肯定不會有什么問題。但是在復(fù)雜的數(shù)據(jù)元素序列組合中,只是根據(jù)單一的某一個關(guān)鍵值排序,直接選擇排序則不保證其穩(wěn)定性,這是直接選擇排序的一個弱點。 面試題 27:編程實現(xiàn)堆排序 堆排序編程實現(xiàn): #include 14 void create

28、heep(int array,int spoint, int len) /生成大根堆 while( ( 2 * spoint + 1 ) len ) int mpoint = 2 * spoint + 1 ; if( ( 2 * spoint + 2 ) len ) if(array 2 * spoint + 1 array 2 * spoint + 2 ) mpoint = 2*spoint+2; if(array spoint = 0; i- ) /將 hr0,lenght-1建成大根堆 createheep(array, i, len); for ( i = len - 1; i 0;

29、i- ) int tmpdata = array0; /與最后一個記錄交換 array0 = arrayi; arrayi = tmpdata; createheep( array, 0, i ); /將 h.r0.i重新調(diào)整為大根堆 return; int main( void ) 15 int array = 5, 4, 7, 3, 9, 1, 6, 8, 2; printf(before sorted:n); /打印排序前數(shù)組內(nèi)容 for ( int i = 0; i 9; i+ ) printf(%d , arrayi); printf(n); heepsort( array, 9 )

30、; /堆排序 printf(after sorted:n); /打印排序后數(shù)組內(nèi)容 for( i = 0; i 9; i+ ) printf( %d , arrayi ); printf( n ); return 0; 說明:堆排序,雖然實現(xiàn)復(fù)雜,但是非常的實用。另外讀者可是自己設(shè)計實現(xiàn)小堆排序的算法。雖然和大堆排序的實現(xiàn)過程相似,但是卻可以加深對堆排序的記憶和理解。 面試題 28:編程實現(xiàn)基數(shù)排序 #include #include #define len 8 typedef struct node /隊列結(jié)點 int data; struct node * next; node,*queu

31、enode; typedef struct queue /隊列 queuenode front; queuenode rear; queue,*queuelink; queuelink createnullqueue( queuelink &q) /創(chuàng)建空隊列 q = null; q = ( queuelink )malloc( sizeof( queue ) ); if( null = q ) printf(fail to malloc null queue!n); return null; 16 q-front = ( queuenode )malloc( sizeof( node

32、 ) ); q-rear = ( queuenode )malloc( sizeof( node ) ); if( null = q-front | null = q-rear ) printf(fail to malloc a new queues fornt or rear!n); return null; q-rear = null; q-front-next= q-rear; return q; int lendata( node data, int len) /計算隊列中各結(jié)點的數(shù)據(jù)的最大位數(shù) int m = 0; int temp = 0; int d; for( int i =

33、0; i 0) d /= 10; temp +; if( temp m ) m = temp; temp = 0; return m; queuelink push( queuelink &q , node node ) /將數(shù)據(jù)壓入隊列 queuenode p1,p; p =( queuenode )malloc( sizeof( node ) ); if( null = p ) printf(fail to malloc a new node!n); return null; p1 = q-front; while(p1-next != null) p1 = p1-next; p-

34、data = node.data; p1-next = p; p-next = q-rear; 17 return null; node pop( queuelink &q) /數(shù)據(jù)出隊列 node temp; temp.data = 0; temp.next = null; queuenode p; p = q-front-next; if( p != q-rear ) temp = *p; q-front-next = p-next; free( p ); p = null; return temp; int isempty( queuelink q) if( q-front-ne

35、xt = q-rear ) return 0; return 1; int main( void ) int i = 0; int max = 0; /記錄結(jié)點中數(shù)據(jù)的最大位數(shù) int d = 10; int power = 1; int k = 0; node arraylen =450, null, 32,null, 781,null, 57 ,null,組 145,null, 613,null, 401,null, 594,null; /隊列結(jié)點數(shù) queuelink queue10; for( i = 0; i 10; i+) createnullqueue( queuei); /初始

36、化隊列數(shù)組 for( i = 0; i len; i+) printf(%d ,arrayi.data); printf(n); max = lendata( array, len ); /計算數(shù)組中關(guān)鍵字的最大位數(shù) printf(%dn,max); 18 for(int j = 0; j max; j+) /按位排序 if(j = 0) power = 1; else power = power *d; for(i = 0; i len; i+) k = arrayi.data /power - (arrayi.data/(power * d) * d; push( queuek, arra

37、yi ); for(int l = 0, k = 0; l d; l+) /排序后出隊列重入數(shù)組 while( isempty( queuel ) ) arrayk+ = pop( queuel ); for( int t = 0; t next = null; 樹結(jié)點入棧函數(shù): void push_path(ppath h, pbtree t) ppath p = h-next; ppath q = h; while( null != p ) 20 q = p; p = p-next; p = ( ppath )malloc( sizeof( path ) ); /申請新結(jié)點 p-next

38、= null; /初始化新結(jié)點 p-tree = t; q-next = p; /新結(jié)點入棧 樹結(jié)點打印函數(shù): void print_path( ppath l ) ppath p = l-next; while( null != p ) /打印當前棧中所有數(shù)據(jù) printf(%d, , p-tree-data); p = p-next; 樹結(jié)點出棧函數(shù): void pop_path( ppath h ) ppath p = h-next; ppath q = h; if( null = p ) /檢驗當前棧是否為空 printf(stack is null!n); return; p = p

39、-next; while( null != p ) /出棧 q = q-next; p = p-next; free( q-next ); /釋放出棧結(jié)點空間 q-next = null; 判斷結(jié)點是否為葉子結(jié)點: int isleaf(pbtree t) return ( t-lchild = null )&( t-rchild=null ); 查找符合條件的路徑: int find_path(pbtree t, int sum, ppath l) 21 push_path( l, t); record += t-data; if( ( record = sum ) & (

40、isleaf( t ) ) ) /打印符合條件的當前路徑 print_path( l ); printf( n ); if( t-lchild != null ) /遞歸查找當前節(jié)點的左孩子 find_path( t-lchild, sum, l); if( t-rchild != null ) /遞歸查找當前節(jié)點的右孩子 find_path( t-rchild, sum, l); record -= t-data; pop_path(l); return 0; 注意:數(shù)據(jù)結(jié)構(gòu)一定要活學活用,例如本題,把所有的結(jié)點都壓入棧,而不符合條件的結(jié)點彈出棧,很容易實現(xiàn)了有效路徑的查找。雖然用鏈表也可以

41、實現(xiàn),但是用棧更利于理解這個問題,即適當?shù)臄?shù)據(jù)結(jié)構(gòu)為更好的算法設(shè)計提供了有利的條件。 面試題 34:寫一個“標準”宏 min 寫一個“標準”宏 min,這個宏輸入兩個參數(shù)并且返回較小的一個。 【答案】 #define min(a,b)(a)=(b)?(a):(b) 注意:在調(diào)用時一定要注意這個宏定義的副作用,如下調(diào)用: (+*p)和經(jīng)常連續(xù)使用。 因此這兩個操作符的返回值應(yīng)該是一個仍舊支持這兩個操作符的流引用。其他的數(shù)據(jù)類型都無法做到這一點。 注意:除了在賦值操作符和流操作符之外的其他的一些操作符中,如+、-、*、/等卻千萬不能返回引用。因為這四個操作符的對象都是右值,因此,它們必須構(gòu)造一個對

42、象作為返回值。 面試題 40:簡述指針常量與常量指針區(qū)別 指針常量是指定義了一個指針,這個指針的值只能在定義時初始化,其他地方不能改變。常量指針是指定義了一個指針,這個指針指向一個只讀的對象,不能通過常量指針來改變這個對象的值。 指針常量強調(diào)的是指針的不可改變性,而常量指針強調(diào)的是指針對其所指對象的不可改變性。 注意:無論是指針常量還是常量指針,其最大的用途就是作為函數(shù)的形式參數(shù),保證實參在被調(diào)用函數(shù)中的不可改變特性。 面試題 41:數(shù)組名和指針的區(qū)別 請寫出以下代碼的打印結(jié)果: #include #include void main(void) char str13=hello world!

43、; 23 char *pstr=hello world!; coutsizeof(str)endl; coutsizeof(pstr)endl; coutstrlen(str)endl; coutstrlen(pstr)endl; return; 【答案】 打印結(jié)果: 13 4 12 12 注意:一定要記得數(shù)組名并不是真正意義上的指針,它的內(nèi)涵要比指針豐富的多。但是當數(shù)組名當做參數(shù)傳遞給函數(shù)后,其失去原來的含義,變作普通的指針。另外要注意 sizeof 不是函數(shù),只是操作符。 面試題 42:如何避免“野指針” “野指針”產(chǎn)生原因及解決辦法如下: (1)指針變量聲明時沒有被初始化。解決辦法:指針

44、聲明時初始化,可以是具體的地址值,也可讓它指向 null。 (2)指針 p 被 free 或者 delete 之后,沒有置為 null。解決辦法:指針指向的內(nèi)存空間被釋放后指針應(yīng)該指向 null。 (3)指針操作超越了變量的作用范圍。解決辦法:在變量的作用域結(jié)束前釋放掉變量的地址空間并且讓指針指向 null。 注意: “野指針” 的解決方法也是編程規(guī)范的基本原則, 平時使用指針時一定要避免產(chǎn)生 “野指針” ,在使用指針前一定要檢驗指針的合法性。 面試題 43:常引用有什么作用 常引用的引入主要是為了避免使用變量的引用時,在不知情的情況下改變變量的值。常引用主要用于定義一個普通變量的只讀屬性的別

45、名、作為函數(shù)的傳入形參,避免實參在調(diào)用函數(shù)中被意外的改變。 說明:很多情況下,需要用常引用做形參,被引用對象等效于常對象,不能在函數(shù)中改變實參的值,這樣的好處是有較高的易讀性和較小的出錯率。 面試題 44:編碼實現(xiàn)字符串轉(zhuǎn)化為數(shù)字 編碼實現(xiàn)函數(shù)atoi(),設(shè)計一個程序,把一個字符串轉(zhuǎn)化為一個整型數(shù)值。例如數(shù)字:“5486321”,轉(zhuǎn)化成字符:5486321。 【答案】 int myatoi(const char * str) 24 int num = 0; /保存轉(zhuǎn)換后的數(shù)值 int isnegative = 0; /記錄字符串中是否有負號 int n =0; char *p = str;

46、if(p = null) /判斷指針的合法性 return -1; while(*p+ != 0) /計算數(shù)字符串度 n+; p = str; if(p0 = -) /判斷數(shù)組是否有負號 isnegative = 1; char temp = 0; for(int i = 0 ; i 9 |temp 0) /濾除非數(shù)字字符 continue; if(num !=0 | temp != 0) /濾除字符串開始的 0 字符 temp -= 0 x30; /將數(shù)字字符轉(zhuǎn)換為數(shù)值 num += temp *int( pow(10 , n - 1 -i) ); if(isnegative) /如果字符串中有負號,將數(shù)值取反 return (0 - num); else return num; /返回轉(zhuǎn)換后的數(shù)值 注意:此段代碼只是實現(xiàn)了十進制字符串到數(shù)字的轉(zhuǎn)化,讀者可以自己去實現(xiàn) 2 進制,8 進制,10進制,16 進制的轉(zhuǎn)化。 面試題 45:簡述 strcpy、sprintf 與 memcpy 的區(qū)別 三者主要有以下不同之處: (1) 操作對象不同, strcpy 的兩個操作對象均為字符串,sprintf 的操作源對象可以是多種數(shù)據(jù)類型,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論