版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 c/c+經(jīng)典面試題 面試題 1:變量的聲明和定義有什么區(qū)別 為變量分配地址和存儲(chǔ)空間的稱為定義,不分配地址的稱為聲明。一個(gè)變量可以在多個(gè)地方聲明,但是只在一個(gè)地方定義。加入 extern 修飾的是變量的聲明,說明此變量將在文件以外或在文件后面部分定義。 說明:很多時(shí)候一個(gè)變量,只是聲明不分配內(nèi)存空間,直到具體使用時(shí)才初始化,分配內(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、指針型變量和“零值”比較的時(shí)候,把“零值”放在左邊,這樣當(dāng)把“=”誤寫成“=”時(shí),編譯器可以報(bào)錯(cuò),否則這種邏輯錯(cuò)誤不容易發(fā)現(xiàn),并且可能導(dǎo)致很嚴(yán)重的后果。 面試題 3:sizeof 和 strlen 的區(qū)別 sizeof 和 strlen 有以下區(qū)別: sizeof 是一個(gè)操作符,strlen 是庫函數(shù)。 sizeof 的參數(shù)可以是數(shù)據(jù)的類型,也可以是變量,而 strlen 只能以結(jié)尾為0的字符串
3、作參數(shù)。 編譯器在編譯時(shí)就計(jì)算出了 sizeof 的結(jié)果。而 strlen 函數(shù)必須在運(yùn)行時(shí)才能計(jì)算出來。并且 sizeof計(jì)算的是數(shù)據(jù)類型占內(nèi)存的大小,而 strlen 計(jì)算的是字符串實(shí)際的長度。 數(shù)組做 sizeof 的參數(shù)不退化,傳遞給 strlen 就退化為指針了。 注意:有些是操作符看起來像是函數(shù),而有些函數(shù)名看起來又像操作符,這類容易混淆的名稱一定要加以區(qū)分,否則遇到數(shù)組名這類特殊數(shù)據(jù)類型作參數(shù)時(shí)就很容易出錯(cuò)。最容易混淆為函數(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ù)。 注意:編程時(shí) static 的記憶性,和全局性的特點(diǎn)可以讓在不同時(shí)期調(diào)用的函數(shù)進(jìn)行通信,傳遞信息,而 c+的靜態(tài)成員則可以在多個(gè)對(duì)象實(shí)例間進(jìn)行通信,傳遞信息。 面試題 5:中的 malloc 和中的 new 有什么區(qū)別 malloc 和 new 有以下不同: (1)new、delete 是操作符,可以重載,只能在 c+中使用。 (2)malloc、free 是函數(shù),可以覆蓋,c、c+中都可以使用。 (3)new 可以調(diào)用對(duì)象的構(gòu)造函數(shù),對(duì)應(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 申請(qǐng)的內(nèi)存空間要用 free 釋放,而 new 申請(qǐng)的內(nèi)存空間要用 delete 釋放,不要混用。因?yàn)閮烧邔?shí)現(xiàn)的機(jī)理不同。 面試題 6:寫一個(gè)“標(biāo)準(zhǔn)”宏 min #define min(a,b)(a)=(b)?(a):(b) 注意:在調(diào)用時(shí)一定要注意這個(gè)宏定義的副作用,如下調(diào)用: (+*p)=(x)?(+*p):(x)。 p 指針就自加了兩次,違背了 min 的本意。 3 面試題 7:一個(gè)指
6、針可以是 volatile 嗎 可以,因?yàn)橹羔樅推胀ㄗ兞恳粯?,有時(shí)也有變化程序的不可控性。常見例:子中斷服務(wù)子程序修改一個(gè)指向一個(gè) buffer 的指針時(shí),必須用 volatile 來修飾這個(gè)指針。 說明:指針是一種普通的變量,從訪問上沒有什么不同于其他變量的特性。其保存的數(shù)值是個(gè)整型數(shù)據(jù),和整型變量不同的是,這個(gè)整型數(shù)據(jù)指向的是一段內(nèi)存地址。 面試題 8:a 和&a 有什么區(qū)別 請(qǐng)寫出以下代碼的打印結(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);時(shí)輸出結(jié)果將是什么呢? 面試題 9:簡述 c、c+程序編譯的內(nèi)存分配情況 c、c+中內(nèi)存分配方式可以分為三種: (1)從靜態(tài)存儲(chǔ)區(qū)域分配: 內(nèi)存在程序編譯時(shí)就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。速度快、不容易出錯(cuò),因?yàn)橛邢到y(tǒng)會(huì)善后。例如全局變量,static 變量等。 (2)在棧上分配: 在執(zhí)
8、行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。 (3)從堆上分配: 即動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用 malloc 或 new 申請(qǐng)任意大小的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用 free 或 delete 釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定, 使用非常靈活。如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會(huì)出現(xiàn)內(nèi)存泄漏,另外頻繁地分配和釋放不同大小的堆空間將會(huì)產(chǎn)生堆內(nèi)碎塊。 一個(gè) c、c+程序編譯時(shí)內(nèi)存分為 5 大存儲(chǔ)區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)、程序代碼區(qū)。 4 面試題
9、10:簡述 strcpy、sprintf 與 memcpy 的區(qū)別 三者主要有以下不同之處: (1) 操作對(duì)象不同, strcpy 的兩個(gè)操作對(duì)象均為字符串,sprintf 的操作源對(duì)象可以是多種數(shù)據(jù)類型,目的操作對(duì)象是字符串, memcpy 的兩個(gè)對(duì)象就是兩個(gè)任意可操作的內(nèi)存地址, 并不限于何種數(shù)據(jù)類型。 (2)執(zhí)行效率不同,memcpy 最高,strcpy 次之,sprintf 的效率最低。 (3)實(shí)現(xiàn)功能不同,strcpy 主要實(shí)現(xiàn)字符串變量間的拷貝,sprintf 主要實(shí)現(xiàn)其他數(shù)據(jù)類型格式到字符串的轉(zhuǎn)化,memcpy 主要是內(nèi)存塊間的拷貝。 說明:strcpy、sprintf 與 me
10、mcpy都可以實(shí)現(xiàn)拷貝的功能,但是針對(duì)的對(duì)象不同,根據(jù)實(shí)際需求,來選擇合適的函數(shù)實(shí)現(xiàn)拷貝功能。 面試題 11:設(shè)置地址為 0 x67a9 的整型變量的值為 0 xaa66 int *ptr; ptr = (int *)0 x67a9; *ptr = 0 xaa66; 說明: 這道題就是強(qiáng)制類型轉(zhuǎn)換的典型例子, 無論在什么平臺(tái)地址長度和整型數(shù)據(jù)的長度是一樣的,即一個(gè)整型數(shù)據(jù)可以強(qiáng)制轉(zhuǎn)換成地址指針類型,只要有意義即可。 面試題 12:面向?qū)ο蟮娜筇卣?面向?qū)ο蟮娜筇卣魇欠庋b性、繼承性和多態(tài)性: 封裝性:將客觀事物抽象成類,每個(gè)類對(duì)自身的數(shù)據(jù)和方法實(shí)行 protection(private, p
11、rotected,public)。 繼承性:廣義的繼承有三種實(shí)現(xiàn)形式:實(shí)現(xiàn)繼承(使用基類的屬性和方法而無需額外編碼的能力)、可視繼承(子窗體使用父窗體的外觀和實(shí)現(xiàn)代碼)、接口繼承(僅使用屬性和方法,實(shí)現(xiàn)滯后到子類實(shí)現(xiàn))。 多態(tài)性:是將父類對(duì)象設(shè)置成為和一個(gè)或更多它的子對(duì)象相等的技術(shù)。用子類對(duì)象給父類對(duì)象賦值之后,父類對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作。 說明:面向?qū)ο蟮娜齻€(gè)特征是實(shí)現(xiàn)面向?qū)ο蠹夹g(shù)的關(guān)鍵,每一個(gè)特征的相關(guān)技術(shù)都非常的復(fù)雜,程序員應(yīng)該多看、多練。 面試題 13:c+的空類有哪些成員函數(shù) 缺省構(gòu)造函數(shù)。 缺省拷貝構(gòu)造函數(shù)。 缺省析構(gòu)函數(shù)。 缺省賦值運(yùn)算符。 缺省
12、取址運(yùn)算符。 缺省取址運(yùn)算符 const。 注意:有些書上只是簡單的介紹了前四個(gè)函數(shù)。沒有提及后面這兩個(gè)函數(shù)。但后面這兩個(gè)函數(shù)也是空類的默認(rèn)函數(shù)。另外需要注意的是,只有當(dāng)實(shí)際使用這些函數(shù)的時(shí)候,編譯器才會(huì)去定義它們。 5 面試題 14:談?wù)勀銓?duì)拷貝構(gòu)造函數(shù)和賦值運(yùn)算符的認(rèn)識(shí) 拷貝構(gòu)造函數(shù)和賦值運(yùn)算符重載有以下兩個(gè)不同之處: (1)拷貝構(gòu)造函數(shù)生成新的類對(duì)象,而賦值運(yùn)算符不能。 (2)由于拷貝構(gòu)造函數(shù)是直接構(gòu)造一個(gè)新的類對(duì)象,所以在初始化這個(gè)對(duì)象之前不用檢驗(yàn)源對(duì)象是否和新建對(duì)象相同。而賦值運(yùn)算符則需要這個(gè)操作,另外賦值運(yùn)算中如果原來的對(duì)象中有內(nèi)存分配要先把內(nèi)存釋放掉 注意:當(dāng)有類中有指針類型的成
13、員變量時(shí),一定要重寫拷貝構(gòu)造函數(shù)和賦值運(yùn)算符,不要使用默認(rèn)的。 面試題 15:用 c+設(shè)計(jì)一個(gè)不能被繼承的類 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ù)是繼承實(shí)現(xiàn)的關(guān)鍵,每次子類對(duì)象構(gòu)造時(shí),首先調(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; /將當(dāng)
15、前結(jié)點(diǎn)插入到翻轉(zhuǎn)后鏈表的開頭 newhead = oldlist; /遞歸處理剩余的鏈表 return ( next=null )? newhead: reverse( t, newhead ); 說明:循環(huán)算法就是圖 10.2圖 10.5 的移動(dòng)過程,比較好理解和想到。遞歸算法的設(shè)計(jì)雖有一點(diǎn)難度,但是理解了循環(huán)算法,再設(shè)計(jì)遞歸算法就簡單多了。 面試題 21:簡述隊(duì)列和棧的異同 隊(duì)列和棧都是線性存儲(chǔ)結(jié)構(gòu),但是兩者的插入和刪除數(shù)據(jù)的操作不同,隊(duì)列是“先進(jìn)先出”,棧是“后進(jìn)先出”。 注意:區(qū)別棧區(qū)和堆區(qū)。堆區(qū)的存取是“順序隨意”,而棧區(qū)是“后進(jìn)先出”。棧由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局
16、部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。堆一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由 os 回收。分配方式類似于鏈表。 它與本題中的堆和棧是兩回事。 堆棧只是一種數(shù)據(jù)結(jié)構(gòu), 而堆區(qū)和棧區(qū)是程序的不同內(nèi)存存儲(chǔ)區(qū)域。 面試題 22:能否用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的功能 結(jié)點(diǎn)結(jié)構(gòu)體: typedef struct node int data; node *next; node,*linkstack; 創(chuàng)建空棧: linkstack createnullstack( linkstack &s) s = (linkstack)malloc( sizeof( node ) ); /申
17、請(qǐng)新結(jié)點(diǎn) if( null = s) printf(fail to malloc a new node.n); 9 return null; s-data = 0; /初始化新結(jié)點(diǎn) s-next = null; return s; 棧的插入函數(shù): linkstack push( linkstack &s, int data) if( null = s) /檢驗(yàn)棧 printf(there no node in stack!); return null; linkstack p = null; p = (linkstack)malloc( sizeof( node ) ); /申請(qǐng)新結(jié)點(diǎn)
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é)點(diǎn) s-next = p; /插入新結(jié)點(diǎn) return s; 出棧函數(shù): node pop( linkstack &s) node temp; temp.data = 0; temp.next = null; if( null = s) /檢驗(yàn)棧 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é)點(diǎn)出棧 s-next = s-next-next; temp = *p; free( p ); p = null; return temp; 雙棧實(shí)現(xiàn)隊(duì)列的入隊(duì)函數(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é)點(diǎn)入棧 while( null != s1-next ) /s1 出棧入 s n = pop( s1 ); push( s, n.data ); return s; 說明:用兩個(gè)棧能夠?qū)崿F(xiàn)一個(gè)隊(duì)列的功能,那用兩個(gè)隊(duì)列能否實(shí)現(xiàn)一個(gè)隊(duì)列的功能呢?結(jié)果是否定的,因?yàn)闂J窍冗M(jìn)后出,將兩個(gè)棧連在一起,就是先進(jìn)先出。而隊(duì)列是現(xiàn)先進(jìn)先出,無論多少個(gè)連在一起都是先進(jìn)先出,而無法實(shí)現(xiàn)先進(jìn)后出。 面
21、試題 23:計(jì)算一顆二叉樹的深度 深度的計(jì)算函數(shù): int depth(bitree t) if(!t) return 0; /判斷當(dāng)前結(jié)點(diǎn)是否為葉子結(jié)點(diǎn) 11 int d1= depth(t-lchild); /求當(dāng)前結(jié)點(diǎn)的左孩子樹的深度 int d2= depth(t-rchild); /求當(dāng)前結(jié)點(diǎn)的右孩子樹的深度 return (d1d2?d1:d2)+1; 注意:根據(jù)二叉樹的結(jié)構(gòu)特點(diǎn),很多算法都可以用遞歸算法來實(shí)現(xiàn)。 面試題 24:編碼實(shí)現(xiàn)直接插入排序 直接插入排序編程實(shí)現(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將保持原位不動(dòng) 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é)點(diǎn)(元素)均可稱為哨兵。引入哨兵后使得查找循環(huán)條件的時(shí)間大約減少了一半,對(duì)于記錄數(shù)較大的文件節(jié)約的時(shí)間就相當(dāng)可觀。類似于排序這樣使用頻率非常高的算法,要盡可能地減少其運(yùn)行時(shí)間。所以不能把上述算法中的哨兵視為雕蟲小技。 面試題 25:編碼實(shí)現(xiàn)冒泡排序 冒泡排序編程實(shí)現(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è)定交換標(biāo)志 for( i = 1; i = i; j- ) /對(duì)當(dāng)前無序區(qū) arrayi.len自下向上掃描 if( arrayj+1 arrayj ) /交換記錄 array0 = arrayj+1; /array0不是哨兵
25、,僅做暫存單元 arrayj+1 = arrayj; arrayj = array0; ischange = 1; /發(fā)生了交換,故將交換標(biāo)志置為真 printf( n ); for( a = 0; a len; a+) /打印本次排序后數(shù)組內(nèi)容 printf( %d , arraya ); if( !ischange ) /本趟排序未發(fā)生交換,提前終止算法 break; printf( n ); return; 13 面試題 26:編碼實(shí)現(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)鍵碼的對(duì)象可能會(huì)顛倒次序,因而直接選擇排序算法是一種不穩(wěn)定的排序方法。在本例中只是例舉了簡單的整形數(shù)組排序,肯定不會(huì)有什么問題。但是在復(fù)雜的數(shù)據(jù)元素序列組合中,只是根據(jù)單一的某一個(gè)關(guān)鍵值排序,直接選擇排序則不保證其穩(wěn)定性,這是直接選擇排序的一個(gè)弱點(diǎn)。 面試題 27:編程實(shí)現(xiàn)堆排序 堆排序編程實(shí)現(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; /與最后一個(gè)記錄交換 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; 說明:堆排序,雖然實(shí)現(xiàn)復(fù)雜,但是非常的實(shí)用。另外讀者可是自己設(shè)計(jì)實(shí)現(xiàn)小堆排序的算法。雖然和大堆排序的實(shí)現(xiàn)過程相似,但是卻可以加深對(duì)堆排序的記憶和理解。 面試題 28:編程實(shí)現(xiàn)基數(shù)排序 #include #include #define len 8 typedef struct node /隊(duì)列結(jié)點(diǎn) int data; struct node * next; node,*queu
31、enode; typedef struct queue /隊(duì)列 queuenode front; queuenode rear; queue,*queuelink; queuelink createnullqueue( queuelink &q) /創(chuàng)建空隊(duì)列 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) /計(jì)算隊(duì)列中各結(jié)點(diǎn)的數(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ù)壓入隊(duì)列 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ù)出隊(duì)列 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é)點(diǎn)中數(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; /隊(duì)列結(jié)點(diǎn)數(shù) queuelink queue10; for( i = 0; i 10; i+) createnullqueue( queuei); /初始
36、化隊(duì)列數(shù)組 for( i = 0; i len; i+) printf(%d ,arrayi.data); printf(n); max = lendata( array, len ); /計(jì)算數(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+) /排序后出隊(duì)列重入數(shù)組 while( isempty( queuel ) ) arrayk+ = pop( queuel ); for( int t = 0; t next = null; 樹結(jié)點(diǎn)入棧函數(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 ) ); /申請(qǐng)新結(jié)點(diǎn) p-next
38、= null; /初始化新結(jié)點(diǎn) p-tree = t; q-next = p; /新結(jié)點(diǎn)入棧 樹結(jié)點(diǎn)打印函數(shù): void print_path( ppath l ) ppath p = l-next; while( null != p ) /打印當(dāng)前棧中所有數(shù)據(jù) printf(%d, , p-tree-data); p = p-next; 樹結(jié)點(diǎn)出棧函數(shù): void pop_path( ppath h ) ppath p = h-next; ppath q = h; if( null = p ) /檢驗(yàn)當(dāng)前棧是否為空 printf(stack is null!n); return; p = p
39、-next; while( null != p ) /出棧 q = q-next; p = p-next; free( q-next ); /釋放出棧結(jié)點(diǎn)空間 q-next = null; 判斷結(jié)點(diǎn)是否為葉子結(jié)點(diǎn): 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 ) ) ) /打印符合條件的當(dāng)前路徑 print_path( l ); printf( n ); if( t-lchild != null ) /遞歸查找當(dāng)前節(jié)點(diǎn)的左孩子 find_path( t-lchild, sum, l); if( t-rchild != null ) /遞歸查找當(dāng)前節(jié)點(diǎn)的右孩子 find_path( t-rchild, sum, l); record -= t-data; pop_path(l); return 0; 注意:數(shù)據(jù)結(jié)構(gòu)一定要活學(xué)活用,例如本題,把所有的結(jié)點(diǎn)都?jí)喝霔#环蠗l件的結(jié)點(diǎn)彈出棧,很容易實(shí)現(xiàn)了有效路徑的查找。雖然用鏈表也可以
41、實(shí)現(xiàn),但是用棧更利于理解這個(gè)問題,即適當(dāng)?shù)臄?shù)據(jù)結(jié)構(gòu)為更好的算法設(shè)計(jì)提供了有利的條件。 面試題 34:寫一個(gè)“標(biāo)準(zhǔn)”宏 min 寫一個(gè)“標(biāo)準(zhǔn)”宏 min,這個(gè)宏輸入兩個(gè)參數(shù)并且返回較小的一個(gè)。 【答案】 #define min(a,b)(a)=(b)?(a):(b) 注意:在調(diào)用時(shí)一定要注意這個(gè)宏定義的副作用,如下調(diào)用: (+*p)和經(jīng)常連續(xù)使用。 因此這兩個(gè)操作符的返回值應(yīng)該是一個(gè)仍舊支持這兩個(gè)操作符的流引用。其他的數(shù)據(jù)類型都無法做到這一點(diǎn)。 注意:除了在賦值操作符和流操作符之外的其他的一些操作符中,如+、-、*、/等卻千萬不能返回引用。因?yàn)檫@四個(gè)操作符的對(duì)象都是右值,因此,它們必須構(gòu)造一個(gè)對(duì)
42、象作為返回值。 面試題 40:簡述指針常量與常量指針區(qū)別 指針常量是指定義了一個(gè)指針,這個(gè)指針的值只能在定義時(shí)初始化,其他地方不能改變。常量指針是指定義了一個(gè)指針,這個(gè)指針指向一個(gè)只讀的對(duì)象,不能通過常量指針來改變這個(gè)對(duì)象的值。 指針常量強(qiáng)調(diào)的是指針的不可改變性,而常量指針強(qiáng)調(diào)的是指針對(duì)其所指對(duì)象的不可改變性。 注意:無論是指針常量還是常量指針,其最大的用途就是作為函數(shù)的形式參數(shù),保證實(shí)參在被調(diào)用函數(shù)中的不可改變特性。 面試題 41:數(shù)組名和指針的區(qū)別 請(qǐng)寫出以下代碼的打印結(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)涵要比指針豐富的多。但是當(dāng)數(shù)組名當(dāng)做參數(shù)傳遞給函數(shù)后,其失去原來的含義,變作普通的指針。另外要注意 sizeof 不是函數(shù),只是操作符。 面試題 42:如何避免“野指針” “野指針”產(chǎn)生原因及解決辦法如下: (1)指針變量聲明時(shí)沒有被初始化。解決辦法:指針
44、聲明時(shí)初始化,可以是具體的地址值,也可讓它指向 null。 (2)指針 p 被 free 或者 delete 之后,沒有置為 null。解決辦法:指針指向的內(nèi)存空間被釋放后指針應(yīng)該指向 null。 (3)指針操作超越了變量的作用范圍。解決辦法:在變量的作用域結(jié)束前釋放掉變量的地址空間并且讓指針指向 null。 注意: “野指針” 的解決方法也是編程規(guī)范的基本原則, 平時(shí)使用指針時(shí)一定要避免產(chǎn)生 “野指針” ,在使用指針前一定要檢驗(yàn)指針的合法性。 面試題 43:常引用有什么作用 常引用的引入主要是為了避免使用變量的引用時(shí),在不知情的情況下改變變量的值。常引用主要用于定義一個(gè)普通變量的只讀屬性的別
45、名、作為函數(shù)的傳入形參,避免實(shí)參在調(diào)用函數(shù)中被意外的改變。 說明:很多情況下,需要用常引用做形參,被引用對(duì)象等效于常對(duì)象,不能在函數(shù)中改變實(shí)參的值,這樣的好處是有較高的易讀性和較小的出錯(cuò)率。 面試題 44:編碼實(shí)現(xiàn)字符串轉(zhuǎn)化為數(shù)字 編碼實(shí)現(xiàn)函數(shù)atoi(),設(shè)計(jì)一個(gè)程序,把一個(gè)字符串轉(zhuǎn)化為一個(gè)整型數(shù)值。例如數(shù)字:“5486321”,轉(zhuǎn)化成字符:5486321。 【答案】 int myatoi(const char * str) 24 int num = 0; /保存轉(zhuǎn)換后的數(shù)值 int isnegative = 0; /記錄字符串中是否有負(fù)號(hào) int n =0; char *p = str;
46、if(p = null) /判斷指針的合法性 return -1; while(*p+ != 0) /計(jì)算數(shù)字符串度 n+; p = str; if(p0 = -) /判斷數(shù)組是否有負(fù)號(hào) 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) /如果字符串中有負(fù)號(hào),將數(shù)值取反 return (0 - num); else return num; /返回轉(zhuǎn)換后的數(shù)值 注意:此段代碼只是實(shí)現(xiàn)了十進(jìn)制字符串到數(shù)字的轉(zhuǎn)化,讀者可以自己去實(shí)現(xiàn) 2 進(jìn)制,8 進(jìn)制,10進(jìn)制,16 進(jìn)制的轉(zhuǎn)化。 面試題 45:簡述 strcpy、sprintf 與 memcpy 的區(qū)別 三者主要有以下不同之處: (1) 操作對(duì)象不同, strcpy 的兩個(gè)操作對(duì)象均為字符串,sprintf 的操作源對(duì)象可以是多種數(shù)據(jù)類型,
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 贛東學(xué)院《中外舞蹈史(一)》2023-2024學(xué)年第一學(xué)期期末試卷
- 甘肅中醫(yī)藥大學(xué)《馬屬動(dòng)物遺傳學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 七年級(jí)英語上冊(cè)Module8ChoosingpresentsUnit2Sheoftengoestoconcerts教案含反思新版外研版
- 三年級(jí)數(shù)學(xué)下冊(cè)六認(rèn)識(shí)分?jǐn)?shù)第5課時(shí)練習(xí)五教案北師大版
- 三年級(jí)科學(xué)上冊(cè)第四單元人與水8水教案首師大版1
- 九年級(jí)化學(xué)上冊(cè)第四章生命之源-水4.3質(zhì)量守恒定律同步練習(xí)新版粵教版
- 小學(xué)生場景描寫課件
- 高二物理期末模擬卷(考試版A3)【測試范圍:人教版選必一選必二第一、二章】(新八省通-用)
- 2025年6月日歷表(含農(nóng)歷-周數(shù)-方便記事備忘)
- 傳染病防治的法律法規(guī)-課件
- 2024年九年級(jí)初中數(shù)學(xué)競賽輔導(dǎo)講義及習(xí)題解答 第19講 轉(zhuǎn)化靈活的圓中角
- 托福聽力課件
- 事業(yè)單位年度考核方案
- 2024年土地管理法
- 醫(yī)學(xué)統(tǒng)計(jì)學(xué):醫(yī)學(xué)統(tǒng)計(jì)學(xué)課后習(xí)題答案
- 框架玻璃幕墻施工工藝
- 全球50強(qiáng)藥企官網(wǎng)及LOGO匯總
- 2024年福建省投資開發(fā)集團(tuán)有限責(zé)任公司招聘筆試參考題庫含答案解析
- 23秋國家開放大學(xué)《法律職業(yè)倫理》形考任務(wù)1-3參考答案
- 全國自然教育中長期發(fā)展規(guī)劃
- 中等職業(yè)學(xué)校2024年中等職業(yè)教育質(zhì)量年度報(bào)告
評(píng)論
0/150
提交評(píng)論