版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1.new、delete、malloc、free關(guān)系delete會調(diào)用對象的析構(gòu)函數(shù),和new相應(yīng)free只會釋放內(nèi)存,new調(diào)用構(gòu)造函數(shù)。malloc與free是C++/C語言的標(biāo)準(zhǔn)庫函數(shù),new/delete是C++的運(yùn)算符。它們都可用于申請動態(tài)內(nèi)存和釋放內(nèi)存。對于非內(nèi)部數(shù)據(jù)類型的對象而言,光用maloc/free無法滿足動態(tài)對象的規(guī)定。對象在創(chuàng)建的同時(shí)要自動執(zhí)行構(gòu)造函數(shù),對象在消亡之前要自動執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫函數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不可以把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。因此C++語言需要一個(gè)能完畢動態(tài)內(nèi)存分派和初始化工作的運(yùn)算符new,以及一個(gè)能完畢清理與釋放內(nèi)存工作的運(yùn)算符delete。注意new/delete不是庫函數(shù)。2.delete與delete[]區(qū)別?delete只會調(diào)用一次析構(gòu)函數(shù),而delete[]會調(diào)用每一個(gè)成員的析構(gòu)函數(shù)。在MoreEffectiveC++中有更為具體的解釋:“當(dāng)delete操作符用于數(shù)組時(shí),它為每個(gè)數(shù)組元素調(diào)用析構(gòu)函數(shù),然后調(diào)用operat(yī)ordelete來釋放內(nèi)存?!眃elete與New配套,delete[]與new[]配套MemTest*mTest1=newMemTest[10];MemTest*mTest2=newMemTest;int*pInt1=newint[10];int*pInt2=newint;delete[]pInt1;//-1-delete[]pInt2;//-2-delete[]mTest1;//-3-delete[]mTest2;//-4-在-4-處報(bào)錯(cuò)。這就說明:對于內(nèi)建簡樸數(shù)據(jù)類型,delete和delete[]功能是相同的。對于自定義的復(fù)雜數(shù)據(jù)類型,delete和delete[]不能互用。delete[]刪除一個(gè)數(shù)組,delete刪除一個(gè)指針簡樸來說,用new分派的內(nèi)存用delete刪除用new[]分派的內(nèi)存用delete[]刪除delete[]會調(diào)用數(shù)組元素的析構(gòu)函數(shù)。內(nèi)部數(shù)據(jù)類型沒有析構(gòu)函數(shù),所以問題不大。假如你在用delete時(shí)沒用括號,delete就會認(rèn)為指向的是單個(gè)對象,否則,它就會認(rèn)為指向的是一個(gè)數(shù)組。3.CC++JAVA共同點(diǎn),不同之處?4.繼承優(yōu)缺陷。類繼承是在編譯時(shí)刻靜態(tài)定義的,且可直接使用,類繼承可以較方便地改變父類的實(shí)現(xiàn)。但是類繼承也有一些局限性之處。一方面,由于繼承在編譯時(shí)刻就定義了,所以無法在運(yùn)營時(shí)刻改變從父類繼承的實(shí)現(xiàn)。更糟的是,父類通常至少定義了子類的部分行為,父類的任何改變都也許影響子類的行為。假如繼承下來的實(shí)現(xiàn)不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關(guān)系限制了靈活性并最終限制了復(fù)用性。(待補(bǔ)充)5.C++有哪些性質(zhì)(面向?qū)ο筇攸c(diǎn))?封裝,繼承和多態(tài)。在面向?qū)ο蟪绦蛟O(shè)計(jì)語言中,封裝是運(yùn)用可重用成分構(gòu)造軟件系統(tǒng)的特性,它不僅支持系統(tǒng)的可重用性,并且尚有助于提高系統(tǒng)的可擴(kuò)充性;消息傳遞可以實(shí)現(xiàn)發(fā)送一個(gè)通用的消息而調(diào)用不同的方法;封裝是實(shí)現(xiàn)信息隱蔽的一種技術(shù),其目的是使類的定義和實(shí)現(xiàn)分離。6.子類析構(gòu)時(shí)要調(diào)用父類的析構(gòu)函數(shù)嗎?析構(gòu)函數(shù)調(diào)用的順序是先派生類的析構(gòu)后基類的析構(gòu),也就是說在基類的的析構(gòu)調(diào)用的時(shí)候,派生類的信息已經(jīng)所有銷毀了。定義一個(gè)對象時(shí)先調(diào)用基類的構(gòu)造函數(shù)、然后調(diào)用派生類的構(gòu)造函數(shù);析構(gòu)的時(shí)候恰好相反:先調(diào)用派生類的析構(gòu)函數(shù)、然后調(diào)用基類的析構(gòu)函數(shù)JAVA無析構(gòu)函數(shù)深拷貝和淺拷貝7.多態(tài),虛函數(shù),純虛函數(shù)8.求下面函數(shù)的返回值(微軟)intfunc(x)
{?
intcountx=0;
while(x)?
{?
countx++;?
x=x&(x-1);
}?
returncountx;?}
假定x=9999。答案:8。思緒:將x轉(zhuǎn)化為2進(jìn)制,看具有的1的個(gè)數(shù)。9.什么是“引用”?申明和使用“引用”要注意哪些問題?答:引用就是某個(gè)目的變量的“別名”(alias),對引用的操作與對變量直接操作效果完全相同。申明一個(gè)引用的時(shí)候,牢記要對其進(jìn)行初始化。引用聲明完畢后,相稱于目的變量名有兩個(gè)名稱,即該目的原名稱和引用名,不能再把該引用名作為其他變量名的別名。聲明一個(gè)引用,不是新定義了一個(gè)變量,它只表達(dá)該引用名是目的變量名的一個(gè)別名,它自身不是一種數(shù)據(jù)類型,因此引用自身不占存儲單元,系統(tǒng)也不給引用分派存儲單元。不能建立數(shù)組的引用。10.將“引用”作為函數(shù)參數(shù)有哪些特點(diǎn)?(1)傳遞引用給函數(shù)與傳遞指針的效果是同樣的。這時(shí),被調(diào)函數(shù)的形參就成為本來主調(diào)函數(shù)中的實(shí)參變量或?qū)ο蟮囊粋€(gè)別名來使用,所以在被調(diào)函數(shù)中對形參變量的操作就是對其相應(yīng)的目的對象(在主調(diào)函數(shù)中)的操作。(2)使用引用傳遞函數(shù)的參數(shù),在內(nèi)存中并沒有產(chǎn)生實(shí)參的副本,它是直接對實(shí)參操作;而使用一般變量傳遞函數(shù)的參數(shù),當(dāng)發(fā)生函數(shù)調(diào)用時(shí),需要給形參分派存儲單元,形參變量是實(shí)參變量的副本;假如傳遞的是對象,還將調(diào)用拷貝構(gòu)造函數(shù)。因此,當(dāng)參數(shù)傳遞的數(shù)據(jù)較大時(shí),用引用比用一般變量傳遞參數(shù)的效率和所占空間都好。(3)使用指針作為函數(shù)的參數(shù)雖然也能達(dá)成與使用引用的效果,但是,在被調(diào)函數(shù)中同樣要給形參分派存儲單元,且需要反復(fù)使用"*指針變量名"的形式進(jìn)行運(yùn)算,這很容易產(chǎn)生錯(cuò)誤且程序的閱讀性較差;另一方面,在主調(diào)函數(shù)的調(diào)用點(diǎn)處,必須用變量的地址作為實(shí)參。而引用更容易使用,更清楚。11.在什么時(shí)候需要使用“常引用”?假如既要運(yùn)用引用提高程序的效率,又要保護(hù)傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被改變,就應(yīng)使用常引用。常引用聲明方式:const類型標(biāo)記符&引用名=目的變量名;例1inta;constint&ra=a;ra=1;//錯(cuò)誤a=1;//對的例2stringfoo();voidbar(string&s);那么下面的表達(dá)式將是非法的:bar(foo());bar("helloworld");因素在于foo()和"helloworld"串都會產(chǎn)生一個(gè)臨時(shí)對象,而在C++中,這些臨時(shí)對象都是const類型的。因此上面的表達(dá)式就是試圖將一個(gè)const類型的對象轉(zhuǎn)換為非const類型,這是非法的。引用型參數(shù)應(yīng)當(dāng)在能被定義為const的情況下,盡量定義為const。12.將“引用”作為函數(shù)返回值類型的格式、好處和需要遵守的規(guī)則?格式:類型標(biāo)記符&函數(shù)名(形參列表及類型說明){//函數(shù)體}好處:在內(nèi)存中不產(chǎn)生被返回值的副本;(注意:正是由于這點(diǎn)因素,所以返回一個(gè)局部變量的引用是不可取的。由于隨著該局部變量生存期的結(jié)束,相應(yīng)的引用也會失效,產(chǎn)生runtimeerror!注意事項(xiàng):(1)不能返回局部變量的引用。這條可以參照EffectiveC++[1]的Item31。重要因素是局部變量會在函數(shù)返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進(jìn)入未知狀態(tài)。(2)不能返回函數(shù)內(nèi)部new分派的內(nèi)存的引用。這條可以參照EffectiveC++[1]的Item31。雖然不存在局部變量的被動銷毀問題,可對于這種情況(返回函數(shù)內(nèi)部new分派內(nèi)存的引用),又面臨其它尷尬局面。例如,被函數(shù)返回的引用只是作為一個(gè)臨時(shí)變量出現(xiàn),而沒有被賦予一個(gè)實(shí)際的變量,那么這個(gè)引用所指向的空間(由new分派)就無法釋放,導(dǎo)致memoryleak。(3)可以返回類成員的引用,但最佳是const。這條原則可以參照EffectiveC++[1]的Item30。重要因素是當(dāng)對象的屬性是與某種業(yè)務(wù)規(guī)則(businessrule)相關(guān)聯(lián)的時(shí)候,其賦值經(jīng)常與某些其它屬性或者對象的狀態(tài)有關(guān),因此有必要將賦值操作封裝在一個(gè)業(yè)務(wù)規(guī)則當(dāng)中。假如其它對象可以獲得該屬性的非常量引用(或指針),那么對該屬性的單純賦值就會破壞業(yè)務(wù)規(guī)則的完整性。(4)流操作符重載返回值申明為“引用”的作用:流操作符<<和>>,這兩個(gè)操作符經(jīng)常希望被連續(xù)使用,例如:cout<<"hello"<<endl;因此這兩個(gè)操作符的返回值應(yīng)當(dāng)是一個(gè)仍然支持這兩個(gè)操作符的流引用??蛇x的其它方案涉及:返回一個(gè)流對象和返回一個(gè)流對象指針。但是對于返回一個(gè)流對象,程序必須重新(拷貝)構(gòu)造一個(gè)新的流對象,也就是說,連續(xù)的兩個(gè)<<操作符事實(shí)上是針對不同對象的!這無法讓人接受。對于返回一個(gè)流指針則不能連續(xù)使用<<操作符。因此,返回一個(gè)流對象引用是惟一選擇。這個(gè)唯一選擇很關(guān)鍵,它說明了引用的重要性以及無可替代性,也許這就是C++語言中引入引用這個(gè)概念的因素吧。賦值操作符=。這個(gè)操作符象流操作符同樣,是可以連續(xù)使用的,例如:x=j=10;或者(x=10)=100;賦值操作符的返回值必須是一個(gè)左值,以便可以被繼續(xù)賦值。因此引用成了這個(gè)操作符的惟一返回值選擇。例3#include<iostream.h>
int&put(intn);?intvals[10];?interror=-1;?voidmain()?{
put(0)=10;//以put(0)函數(shù)值作為左值,等價(jià)于vals[0]=10;?put(9)=20;//以put(9)函數(shù)值作為左值,等價(jià)于vals[9]=20;?cout<<vals[0];
cout<<vals[9];?}?int&put(intn)
{
if(n>=0&&n<=9)returnvals[n];
else{cout<<"subscripterror";returnerror;}?}(5)在此外的一些操作符中,卻千萬不能返回引用:+-*/四則運(yùn)算符。它們不能返回引用,EffectiveC++[1]的Item23具體的討論了這個(gè)問題。重要因素是這四個(gè)操作符沒有sidee(cuò)ffect,因此,它們必須構(gòu)造一個(gè)對象作為返回值,可選的方案涉及:返回一個(gè)對象、返回一個(gè)局部變量的引用,返回一個(gè)new分派的對象的引用、返回一個(gè)靜態(tài)對象引用。根據(jù)前面提到的引用作為返回值的三個(gè)規(guī)則,第2、3兩個(gè)方案都被否決了。靜態(tài)對象的引用又由于((a+b)==(c+d))會永遠(yuǎn)為true而導(dǎo)致錯(cuò)誤。所以可選的只剩下返回一個(gè)對象了。13.“引用”與多態(tài)的關(guān)系?引用是除指針外另一個(gè)可以產(chǎn)生多態(tài)效果的手段。這意味著,一個(gè)基類的引用可以指向它的派生類實(shí)例。例4ClassA;ClassB:ClassA{...};
Bb;A&ref=b;14.“引用”與指針的區(qū)別是什么?1)引用必須被初始化,指針不必。2)引用初始化以后不能被改變,指針可以改變所指的對象。2)不存在指向空值的引用,但是存在指向空值的指針。指針通過某個(gè)指針變量指向一個(gè)對象后,對它所指向的變量間接操作。程序中使用指針,程序的可讀性差;而引用自身就是目的變量的別名,對引用的操作就是對目的變量的操作。此外,就是上面提到的對函數(shù)傳ref和pointer的區(qū)別。15.什么時(shí)候需要“引用”?流操作符<<和>>、賦值操作符=的返回值、拷貝構(gòu)造函數(shù)的參數(shù)、賦值操作符=的參數(shù)、其它情況都推薦使用引用。以上2-8參考:16.結(jié)構(gòu)與聯(lián)合有和區(qū)別?(1).結(jié)構(gòu)和聯(lián)合都是由多個(gè)不同的數(shù)據(jù)類型成員組成,但在任何同一時(shí)刻,聯(lián)合中只存放了一個(gè)被選中的成員(所有成員共用一塊地址空間),而結(jié)構(gòu)的所有成員都存在(不同成員的存放地址不同)。
?
(2).對于聯(lián)合的不同成員賦值,將會對其它成員重寫,
本來成員的值就不存在了,而對于結(jié)構(gòu)的不同成員賦值是互不影響的。17.面關(guān)于“聯(lián)合”的題目的輸出?a)#include<stdio.h>
union?{
inti;
charx[2];
}a;void
main()?{?a.x[0]=10;?a.x[1]=1;
printf("%d",a.i);?}?答案:266(低位低地址,高位高地址,內(nèi)存占用情況是Ox010A)b)main()?
{?
union{
/*定義一個(gè)聯(lián)合*/
inti;?
struct{
/*在聯(lián)合中定義一個(gè)結(jié)構(gòu)*/?
charfirst;?
charsecond;?
}half;
}number;
number.i=0x4241;
/*聯(lián)合成員賦值*/?
printf("%c%cn",number.half.first,mumber.half.second);
number.half.first='a';
/*聯(lián)合中結(jié)構(gòu)成員賦值*/
number.half.second='b';
printf("%xn",number.i);?
getch();?
}
答案:AB
(0x41相應(yīng)'A',是低位;Ox42相應(yīng)'B',是高位)
6261(number.i和number.half共用一塊地址空間)18.關(guān)聯(lián)、聚合(Aggregat(yī)ion)以及組合(Composition)的區(qū)別?涉及到UML中的一些概念:關(guān)聯(lián)是表達(dá)兩個(gè)類的一般性聯(lián)系,比如“學(xué)生”和“老師”就是一種關(guān)聯(lián)關(guān)系;聚合表達(dá)has-a的關(guān)系,是一種相對松散的關(guān)系,聚合類不需要對被聚合類負(fù)責(zé),如下圖所示,用空的菱形表達(dá)聚合關(guān)系:從實(shí)現(xiàn)的角度講,聚合可以表達(dá)為:classA{...}
classB{A*a;.....}而組合表達(dá)contains-a的關(guān)系,關(guān)聯(lián)性強(qiáng)于聚合:組合類與被組合類有相同的生命周期,組合類要對被組合類負(fù)責(zé),采用實(shí)心的菱形表達(dá)組合關(guān)系:實(shí)現(xiàn)的形式是:classA{...}classB{Aa;...}27.
main函數(shù)執(zhí)行以前,還會執(zhí)行什么代碼?答案:全局對象的構(gòu)造函數(shù)會在main函數(shù)之前執(zhí)行。28.
描述內(nèi)存分派方式以及它們的區(qū)別?1)從靜態(tài)存儲區(qū)域分派。內(nèi)存在程序編譯時(shí)就已經(jīng)分派好,這塊內(nèi)存在程序的整個(gè)運(yùn)營期間都存在。例如全局變量,static變量。
2)在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲單元自動被釋放。棧內(nèi)存分派運(yùn)算內(nèi)置于解決器的指令集。
3)從堆上分派,亦稱動態(tài)內(nèi)存分派。程序在運(yùn)營時(shí)用malloc或new申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但問題也最多。29.struct和class的區(qū)別答案:struct的成員默認(rèn)是公有的,而類的成員默認(rèn)是私有的。struct和class在其他方面是功能相稱的。從感情上講,大多數(shù)的開發(fā)者感到類和結(jié)構(gòu)有很大的差別。感覺上結(jié)構(gòu)僅僅象一堆缺少封裝和功能的開放的內(nèi)存位,而類就象活的并且可靠的社會成員,它有智能服務(wù),有牢固的封裝屏障和一個(gè)良好定義的接口。既然大多數(shù)人都這么認(rèn)為,那么只有在你的類有很少的方法并且有公有數(shù)據(jù)(這種事情在良好設(shè)計(jì)的系統(tǒng)中是存在的!)時(shí),你也許應(yīng)當(dāng)使用struct關(guān)鍵字,否則,你應(yīng)當(dāng)使用class關(guān)鍵字。
30.當(dāng)一個(gè)類A中沒有任何成員變量與成員函數(shù),這時(shí)sizeof(A)的值是多少?答案:假如不是零,請解釋一下編譯器為什么沒有讓它為零。(Autodesk)肯定不是零。舉個(gè)反例,假如是零的話,聲明一個(gè)classA[10]對象數(shù)組,而每一個(gè)對象占用的空間是零,這時(shí)就沒辦法區(qū)分A[0],A[1]…了。值為1.32.
比較C++中的4種類型轉(zhuǎn)換方式?請參考:,重點(diǎn)是static_cast,dynamic_cast和reinterpret_cast的區(qū)別和應(yīng)用。dynamic_casts在幫助你瀏覽繼承層次上是有限制的。它不能被用于缺少虛函數(shù)的類型上,它被用于安全地沿著類的繼承關(guān)系向下進(jìn)行類型轉(zhuǎn)換。如你想在沒有繼承關(guān)系的類型中進(jìn)行轉(zhuǎn)換,你也許想到static_cast44.寫一個(gè)在一個(gè)字符串(n)中尋找一個(gè)子串(m)第一個(gè)位置的函數(shù)。KMP算法效率最佳,時(shí)間復(fù)雜度是O(n+m),詳見:48.指針找錯(cuò)題?分析這些面試題,自身包含很強(qiáng)的趣味性;而作為一名研發(fā)人員,通過對這些面試題的進(jìn)一步剖析則可進(jìn)一步增強(qiáng)自身的內(nèi)功。?2.找錯(cuò)題試題1:
以下是引用片段:
voidtest1()//數(shù)組越界
{charstring[10];
char*str1="";
strcpy(string,str1);}試題2:
以下是引用片段:
voidtest2()
{charstring[10],str1[10];
inti;?for(i=0;i<10;i++)?{str1='a';}
strcpy(string,str1);?}?試題3:
以下是引用片段:
voidtest3(char*str1)
{charstring[10];
if(strlen(str1)<=10)
{strcpy(string,str1);}?}
解答:試題1字符串str1需要11個(gè)字節(jié)才干存放下(涉及末尾的’\0’),而string只有10個(gè)字節(jié)的空間,strcpy會導(dǎo)致數(shù)組越界;試題2,假如面試者指出字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束可以給3分;假如面試者指出strcpy(string,str1)調(diào)用使得從str1內(nèi)存起復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不擬定性可以給7分,在此基礎(chǔ)上指出庫函數(shù)strcpy工作方式的給10分;?對試題3,if(strlen(str1)<=10)應(yīng)改為if(strlen(str1)<10),由于strlen的結(jié)果未記錄’\0’所占用的1個(gè)字節(jié)。剖析:考核對基本功的掌握(1)字符串以’\0’結(jié)尾;(2)對數(shù)組越界把握的敏感度;(3)庫函數(shù)strcpy的工作方式,49.假如編寫一個(gè)標(biāo)準(zhǔn)strcpy函數(shù)?總分值為10,下面給出幾個(gè)不同得分的答案:2分以下是引用片段:
voidstrcpy(char*strDest,char*strSrc)
{?while((*strDest++=*strSrc++)!=‘\0’);
}
4分以下是引用片段:
voidstrcpy(char*strDest,constchar*strSrc)?//將源字符串加const,表白其為輸入?yún)?shù),加2分
{while((*strDest++=*strSrc++)!=‘\0’);}?7分以下是引用片段:?voidstrcpy(char*strDest,constchar*strSrc)
{//對源地址和目的地址加非0斷言,加3分
assert((strDest!=NULL)&&(strSrc!=NULL));
while((*strDest++=*strSrc++)!=‘\0’);}
10分以下是引用片段://為了實(shí)現(xiàn)鏈?zhǔn)讲僮?,將目的地址返回,?分!?char*strcpy(char*strDest,constchar*strSrc)?{assert((strDest!=NULL)&&(strSrc!=NULL));//對源地址和目的地址加非0斷言?char*address=strDest;
while((*strDest++=*strSrc++)!=‘\0’);?returnaddress;//為了實(shí)現(xiàn)鏈?zhǔn)讲僮?將目的地址返回}從2分到10分的幾個(gè)答案我們可以清楚的看到,小小的strcpy居然暗藏著這么多玄機(jī),真不是蓋的!需要多么扎實(shí)的基本功才干寫一個(gè)完美的strcpy啊!
(4)對strlen的掌握,它沒有涉及字符串末尾的'\0'。讀者看了不同分值的strcpy版本,應(yīng)當(dāng)也可以寫出一個(gè)10分的strlen函數(shù)了,intstrlen(constchar*str)//輸入?yún)?shù)const以下是引用片段:
{
assert(strt!=NULL);//斷言字符串地址非0
intlen=0;//注,一定要初始化。?while((*str++)!='\0')?{len++;}?returnlen;?}?試題4:以下是引用片段:
voidGetMemory(char*p)//內(nèi)存分派
{p=(char*)malloc(100);}
voidTest(void)?{char*str=NULL;?GetMemory(str);
strcpy(str,"helloworld");?printf(str);}
試題5:以下是引用片段:
char*GetMemory(void)
{charp[]="helloworld";
returnp;}?voidTest(void)
{char*str=NULL;
str=GetMemory();?printf(str);}
試題6:以下是引用片段:
voidGetMemory(char**p,intnum)?{*p=(char*)malloc(num);}?voidTest(void)?{char*str=NULL;
GetMemory(&str,100);?strcpy(str,"hello");?printf(str);}
試題7:以下是引用片段:
voidTest(void)?{char*str=(char*)malloc(100);?strcpy(str,"hello");?free(str);
...//省略的其它語句}
解答:試題4傳入中GetMemory(char*p)函數(shù)的形參為字符串指針,在函數(shù)內(nèi)部修改形參并不能真正的改變傳入形參的值,執(zhí)行完char*str=NULL;GetMemory(str);后的str仍然為NULL;試題5中charp[]="helloworld";returnp;的p[]數(shù)組為函數(shù)內(nèi)的局部自動變量,在函數(shù)返回后,內(nèi)存已經(jīng)被釋放。這是許多程序員常犯的錯(cuò)誤,其根源在于不理解變量的生存期。試題6的GetMemory避免了試題4的問題,傳入GetMemory的參數(shù)為字符串指針的指針,但是在GetMemory中執(zhí)行申請內(nèi)存及賦值語句*p=(char*)malloc(num);后未判斷內(nèi)存是否申請成功,應(yīng)加上:if(*p==NULL){...//進(jìn)行申請內(nèi)存失敗解決}?試題7存在與試題6同樣的問題,在執(zhí)行char*str=(char*)malloc(100);后未進(jìn)行內(nèi)存是否申請成功的判斷;此外,在free(str)后未置str為空,導(dǎo)致也許變成一個(gè)“野”指針,應(yīng)加上:str=NULL;試題6的Test函數(shù)中也未對malloc的內(nèi)存進(jìn)行釋放。
剖析:試題4~7考察面試者對內(nèi)存操作的理解限度,基本功扎實(shí)的面試者一般都能對的的回答其中50~60的錯(cuò)誤。但是要完全解答對的,卻也絕非易事。對內(nèi)存操作的考察重要集中在:(1)指針的理解;(2)變量的生存期及作用范圍;(3)良好的動態(tài)內(nèi)存申請和釋放習(xí)慣。
再看看下面的一段程序有什么錯(cuò)誤:?以下是引用片段:?swap(int*p1,int*p2)?{int*p;?*p=*p1;
*p1=*p2;?*p2=*p;}
在swap函數(shù)中,p是一個(gè)“野”指針,有也許指向系統(tǒng)區(qū),導(dǎo)致程序運(yùn)營的崩潰。在VC++中DEBUG運(yùn)營時(shí)提醒錯(cuò)誤“AccessViolation”。該程序應(yīng)當(dāng)改為?以下是引用片段:
swap(int*p1,int*p2)
{intp;
p=*p1;?*p1=*p2;
*p2=p;}51.h頭文獻(xiàn)中的ifndef/define/endif的作用?答:防止該頭文獻(xiàn)被反復(fù)引用。52.#include<file.h>與#include"file.h"的區(qū)別?答:前者是從StandardLibrary的途徑尋找和引用file.h,而后者是從當(dāng)前工作途徑搜尋并引用file.h。?53.在C++程序中調(diào)用被C編譯器編譯后的函數(shù),為什么要加extern“C”?C++語言支持函數(shù)重載,C語言不支持函數(shù)重載。C++提供了C連接互換指定符號extern“C”解決名字匹配問題。一方面,作為extern是C/C++語言中表白函數(shù)和全局變量作用范圍(可見性)的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。通常,在模塊的頭文獻(xiàn)中對本模塊提供應(yīng)其它模塊引用的函數(shù)和全局變量以關(guān)鍵字extern聲明。例如,假如模塊B欲引用該模塊A中定義的全局變量和函數(shù)時(shí)只需包含模塊A的頭文獻(xiàn)即可。這樣,模塊B中調(diào)用模塊A中的函數(shù)時(shí),在編譯階段,模塊B雖然找不到該函數(shù),但是并不會報(bào)錯(cuò);它會在連接階段中從模塊A編譯生成的目的代碼中找到此函數(shù)。extern"C"是連接申明(linkagedeclaration),被extern"C"修飾的變量和函數(shù)是按照C語言方式編譯和連接的,來看看C++中對類似C的函數(shù)是如何編譯的:作為一種面向?qū)ο蟮恼Z言,C++支持函數(shù)重載,而過程式語言C則不支持。函數(shù)被C++編譯后在符號庫中的名字與C語言的不同。例如,假設(shè)某個(gè)函數(shù)的原型為:voidfoo(intx,inty);該函數(shù)被C編譯器編譯后在符號庫中的名字為_foo,而C++編譯器則會產(chǎn)生像_foo_int_int之類的名字(不同的編譯器也許生成的名字不同,但是都采用了相同的機(jī)制,生成的新名字稱為“mangledname”)。_foo_int_int這樣的名字包含了函數(shù)名、函數(shù)參數(shù)數(shù)量及類型信息,C++就是靠這種機(jī)制來實(shí)現(xiàn)函數(shù)重載的。例如,在C++中,函數(shù)voidfoo(intx,inty)與voidfoo(intx,floaty)編譯生成的符號是不相同的,后者為_foo_int_float。同樣地,C++中的變量除支持局部變量外,還支持類成員變量和全局變量。用戶所編寫程序的類成員變量也許與全局變量同名,我們以"."來區(qū)分。而本質(zhì)上,編譯器在進(jìn)行編譯時(shí),與函數(shù)的解決相似,也為類中的變量取了一個(gè)獨(dú)一無二的名字,這個(gè)名字與用戶程序中同名的全局變量名字不同。未加extern"C"聲明時(shí)的連接方式假設(shè)在C++中,模塊A的頭文獻(xiàn)如下:?//模塊A頭文獻(xiàn)moduleA.h
#ifndefMODULE_A_H?#defineMODULE_A_H?intfoo(intx,inty);
#endif在模塊B中引用該函數(shù):?//模塊B實(shí)現(xiàn)文獻(xiàn)moduleB.cpp
#include"moduleA.h"
foo(2,3);加extern"C"聲明后的編譯和連接方式加extern"C"聲明后,模塊A的頭文獻(xiàn)變?yōu)??//模塊A頭文獻(xiàn)moduleA.h?#ifndefMODULE_A_H?#defineMODULE_A_H
extern"C"intfoo(intx,inty);?#endif在模塊B的實(shí)現(xiàn)文獻(xiàn)中仍然調(diào)用foo(2,3),其結(jié)果是:
(1)模塊A編譯生成foo的目的代碼時(shí),沒有對其名字進(jìn)行特殊解決,采用了C語言的方式;(2)連接器在為模塊B的目的代碼尋找foo(2,3)調(diào)用時(shí),尋找的是未經(jīng)修改的符號名_foo。假如在模塊A中函數(shù)聲明了foo為extern"C"類型,而模塊B中包含的是externintfoo(intx,inty),則模塊B找不到模塊A中的函數(shù);反之亦然。所以,可以用一句話概括extern“C”這個(gè)聲明的真實(shí)目的(任何語言中的任何語法特性的誕生都不是隨意而為的,來源于真實(shí)世界的需求驅(qū)動。我們在思考問題時(shí),不能只停留在這個(gè)語言是怎么做的,還要問一問它為什么要這么做,動機(jī)是什么,這樣我們可以更進(jìn)一步地理解許多問題):實(shí)現(xiàn)C++與C及其它語言的混合編程。明白了C++中extern"C"的設(shè)立動機(jī),我們下面來具體分析extern"C"通常的使用技巧:
extern"C"的慣用法1)在C++中引用C語言中的函數(shù)和變量,在包含C語言頭文獻(xiàn)(假設(shè)為cExample.h)時(shí),需進(jìn)行下列解決:extern"C"?{?#include"cExample.h"?}而在C語言的頭文獻(xiàn)中,對其外部函數(shù)只能指定為extern類型,C語言中不支持extern"C"聲明,在.c文獻(xiàn)中包含了extern"C"時(shí)會出現(xiàn)編譯語法錯(cuò)誤。?C++引用C函數(shù)例子工程中包含的三個(gè)文獻(xiàn)的源代碼如下:
/*c語言頭文獻(xiàn):cExample.h*/
#ifndefC_EXAMPLE_H
#defineC_EXAMPLE_H
externintadd(intx,inty);
#endif
/*c語言實(shí)現(xiàn)文獻(xiàn):cExample.c*/?#include"cExample.h"?intadd(intx,inty)
{
returnx+y;?}
//c++實(shí)現(xiàn)文獻(xiàn),調(diào)用add:cppFile.cpp
extern"C"
{#include"cExample.h"?}?intmain(intargc,char*argv[])
{add(2,3);
return0;?}假如C++調(diào)用一個(gè)C語言編寫的.DLL時(shí),當(dāng)涉及.DLL的頭文獻(xiàn)或聲明接口函數(shù)時(shí),應(yīng)加extern"C"{}。(2)在C中引用C++語言中的函數(shù)和變量時(shí),C++的頭文獻(xiàn)需添加extern"C",但是在C語言中不能直接引用聲明了extern"C"的該頭文獻(xiàn),應(yīng)當(dāng)僅將C文獻(xiàn)中將C++中定義的extern"C"函數(shù)聲明為extern類型。?C引用C++函數(shù)例子工程中包含的三個(gè)文獻(xiàn)的源代碼如下:
//C++頭文獻(xiàn)cppExample.h
#ifndefCPP_EXAMPLE_H
#defineCPP_EXAMPLE_H?extern"C"intadd(intx,inty);?#endif?//C++實(shí)現(xiàn)文獻(xiàn)cppExample.cpp?#include"cppExample.h"
intadd(intx,inty)?{
returnx+y;?}?/*C實(shí)現(xiàn)文獻(xiàn)cFile.c
/*這樣會編譯犯錯(cuò):#include"cExample.h"*/intmain(intargc,char*argv[])
{
add(2,3);?return0;?}15題目的解答請參考《C++中extern“C”含義深層探索》注解:幾道c筆試題(含參考答案)?1.What(yī)isdisplayedwhenf()iscalledgiventhecode:?classNumber{
public:?stringtype;?Number():type(“void”){}
explicitNumber(short):type(“short”){}?Number(int):type(“int”){}?};?voidShow(constNumber&n){cout<<n.type;}?voidf()
{?shorts=42;
Show(s);
}
a)voidb)shortc)intd)Noneoftheabove選C;?雖然傳入的是short類型,但是short類型的構(gòu)造函數(shù)被生命被explicit,也就是只能顯示類型轉(zhuǎn)換,不能使用隱式類型轉(zhuǎn)換
2.Whichisthecorrectoutputforthefollowingcode?doubledArray[2]={4,8},*p,*q;?p=&dArray[0];
q=p+1;?cout<<q–p<<endl;
cout<<(int)q-(int)p<<endl;?a)1and8b)8and4c)4and8d)8and1。第二個(gè)選A;?第一個(gè)是指針加減,按照的是指向地址類型的加減,只跟類型位置有關(guān),q和p指向的數(shù)據(jù)類型以實(shí)際數(shù)據(jù)類型來算差一個(gè)位置,因此是1。而第二個(gè)加減是實(shí)際指針值得加減,在內(nèi)存中一個(gè)double類型占據(jù)8個(gè)字節(jié),因此是854.Sony筆試題1.完畢下列程序?*
*.*.
*..*..*..?*...*...*...*...
*....*....*....*....*....
*.....*.....*.....*.....*.....*.....
*......*......*......*......*......*......*......?*.......*.......*.......*.......*.......*.......*.......*.......
#include<iostream>usingnamespacestd;#defineN8intmain(){?inti,j,k; for(i=0;i<N;i++) {? for(j=0;j<=i;j++)? {? cout<<"*"; for(k=0;k<i;k++)? ?cout<<"."; ?} cout<<endl; } return0;}2.完畢程序,實(shí)現(xiàn)對數(shù)組的降序排序
#include
voidsort();?intmain()
{?intarray[]={45,56,76,234,1,34,23,2,3};//數(shù)字任//意給出
sort();?return0;?}?voidsort()?{
__(dá)______(dá)_______(dá)____________________(dá)_
||?||?|-----------------------------------------------------|?}
3.費(fèi)波那其數(shù)列,1,1,2,3,5……編寫程序求第十項(xiàng)??梢杂眠f歸,也可以用其?他方法,但要說明你選擇的理由。
#include<iostream>usingnamespacestd;intPheponatch(int);intmain(){ cout<<"The10this"<<Pheponatch(10)<<endl;?return0;}intPheponatch(inti){?if(i==1||i==2) return1;?else? returnPheponatch(i-1)+Pheponat(yī)ch(i-2);}4.下列程序運(yùn)營時(shí)會崩潰,請找犯錯(cuò)誤并改正,并且說明因素。
#include<iostream>
#include<stalib>
typedefstruct{?TNode*left;
TNode*right;?intvalue;?}TNode;
TNode*root=NULL;?voidappend(intN);
intmain()?{
append(63);
append(45);?append(32);
append(77);?append(96);?append(21);
append(17);//Again,數(shù)字任意給出?}?voidappend(intN)
{
TNode*NewNode=(TNode*)malloc(sizeof(TNode));
NewNode->value=N;
if(root==NULL)?{?root=NewNode;?return;
}
else?{?TNode*temp;
temp=root;?while((N>=temp.value&&temp.left!=NULL)||(N!=NULL))
{?while(N>=temp.value&&temp.left!=NULL)?temp=temp.left;
while(Ntemp=temp.right;?}?if(N>=temp.value)?temp.left=NewNode;
else?temp.right=NewNode;
return;
}?}55請你分別畫出OSI的七層網(wǎng)絡(luò)結(jié)構(gòu)圖和TCP/IP的五層結(jié)構(gòu)圖。應(yīng)用層:為應(yīng)用程序提供服務(wù)表達(dá)層:解決在兩個(gè)通信系統(tǒng)中互換信息的表達(dá)方式會話層:負(fù)責(zé)維護(hù)兩個(gè)結(jié)點(diǎn)間會話連接的建立、管理和終止,以及數(shù)據(jù)互換傳輸層:向用戶提供可靠的端到端服務(wù)。UDPTCP協(xié)議。網(wǎng)絡(luò)層:通過路由選擇算法為分組通過通信子網(wǎng)選擇最適當(dāng)?shù)耐緩?以及實(shí)現(xiàn)擁塞控制、網(wǎng)絡(luò)互聯(lián)等功能。數(shù)據(jù)傳輸單元是分組。IP地址,路由器,IP協(xié)議。數(shù)據(jù)鏈路層:在物理層提供的服務(wù)基礎(chǔ)上,數(shù)據(jù)鏈路層在通信的實(shí)體間建立數(shù)據(jù)鏈路連接,傳輸一幀為單位的數(shù)據(jù)包(,并采用差錯(cuò)控制與流量控制方法,使有差錯(cuò)的物理線路變成無差錯(cuò)的數(shù)據(jù)鏈路。)物理層:傳輸比特流。傳輸單元是比特。調(diào)制解調(diào)器。56請你具體地解釋一下IP協(xié)議的定義,在哪個(gè)層上面?重要有什么作用?TCP與UDP呢?網(wǎng)絡(luò)層。57.請問互換機(jī)和路由器各自的實(shí)現(xiàn)原理是什么?分別在哪個(gè)層次上面實(shí)現(xiàn)的?互換機(jī):數(shù)據(jù)鏈路層。路由器:網(wǎng)絡(luò)層。58.全局變量和局部變量有什么區(qū)別?是怎么實(shí)現(xiàn)的?操作系統(tǒng)和編譯器是怎么知道的?59.8086是多少位的系統(tǒng)?在數(shù)據(jù)總線上是怎么實(shí)現(xiàn)的??8086微解決器共有4個(gè)16位的段寄存器,在尋址內(nèi)存單元時(shí),用它們直接或間接地存放段地址。代碼段寄存器CS:存放當(dāng)前執(zhí)行的程序的段地址。數(shù)據(jù)段寄存器DS:存放當(dāng)前執(zhí)行的程序所用操作數(shù)的段地址。堆棧段寄存器SS:存放當(dāng)前執(zhí)行的程序所用堆棧的段地址。附加段寄存器ES:存放當(dāng)前執(zhí)行程序中一個(gè)輔助數(shù)據(jù)段的段地址。由cs:ip構(gòu)成指令地址,ss:sp構(gòu)成堆棧的棧頂?shù)刂分羔?。DS和ES用作數(shù)據(jù)段和附加段的段地址(段起始地址或段值)8086/8088微解決器的存儲器管理
1.地址線(碼)與尋址范圍:N條地址線尋址范圍=2N
2.8086有20地址線尋址范圍為1MB由00000H~FFFFFH
3.8086微解決器是一個(gè)16位結(jié)構(gòu),用戶可用的寄存器均為16位:尋址64KB
4.8086/8088采用分段的方法對存儲器進(jìn)行管理。具體做法是:把1MB的存儲器空間提成若干段,每段容量為64KB,每段存儲器的起始地址必須是一個(gè)能被16整除的地址碼,即在20位的二進(jìn)制地址碼中最低4位必須是“0”。每個(gè)段首地址的高16位二進(jìn)制代碼就是該段的段號(稱段基地址)或簡稱段地址,段號保存在段寄存器中。我們可對段寄存器設(shè)立不同的值來使微解決器的存儲器訪問指向不同的段。
5.段內(nèi)的某個(gè)存儲單元相對于該段段首地址的差值,稱為段內(nèi)偏移地址(也叫偏移量)用16位二進(jìn)制代碼表達(dá)。
6.物理地址是由8086/8088芯片地址引線送出的20位地址碼,它用來參與存儲器的地址譯碼,最終讀/寫所訪問的一個(gè)特定的存儲單元。
7.邏輯地址由某段的段地址和段內(nèi)偏移地址(也叫偏移量)兩部分所組成。寫成:段地址:偏移地址(例如,1234H:0088H)。
8.在硬件上起作用的是物理地址,物理地址=段基地址×10H十偏移地址聯(lián)想筆試題
1.設(shè)計(jì)函數(shù)intatoi(char*s)。int
atoi(const
char
*s)
{
if(!str)
returnI(lǐng)NF;?
char
c;
int
i
=
0;
boolisMinus=false;
c=*s;
if(c='-')
{
isMinus=true;s++;}
while(c=*p++)?
{?
if(c>='0'
&&
c<='9')?
i
=
i*10
+
(c-'0');
else?
return
INF;
//Invalid
string?
}
if(isMinus)i=-i;?
return
i;?}2.inti=(j=4,k=8,l=16,m=32);printf(“%d”,i);輸出是多少?32
走人(重要考businessletter格式)。
大唐面試試題1.什么是中斷?中斷發(fā)生時(shí)CPU做什么工作?2.CPU在上電后,進(jìn)入操作系統(tǒng)的main()之前必須做什么工作?3.簡述ISOOSI的物理層Layer1,鏈路層Layer2,網(wǎng)絡(luò)層Layer3的任務(wù)。4.有線電話和無線電話有何區(qū)別?無線電話特別需要注意的是什么?5軟件開發(fā)五個(gè)重要step是什么?6.你在開發(fā)軟件的時(shí)候,這5個(gè)step分別占用的時(shí)間比例是多少?7.makefile文獻(xiàn)的作用是什么?8.UNIX顯示文獻(xiàn)夾中,文獻(xiàn)名的命令是什么?能使文獻(xiàn)內(nèi)容顯示在屏幕的命令是什么?9.(選做)手機(jī)用戶在從一個(gè)基站漫游到另一個(gè)基站的過程中,都會發(fā)生什么??簡答題(每題10分)1.簡述普通電話與IP電話的區(qū)別。2.簡述隨路信令與公路信令的主線區(qū)別。3.說明掩碼的重要作用。4.ss7協(xié)議中,有三大要素決定其具體定位,哪三大要素?5.描述ss7的基本通話過程。6.簡述通信網(wǎng)的組成結(jié)構(gòu)。7.面向連接與面向非連接各有何利弊?8.寫出愛爾蘭的基本計(jì)算公式。9.數(shù)據(jù)網(wǎng)重要有哪些設(shè)備?10.中國一號協(xié)議是如何在被叫號碼中插入主叫號碼的?
東信筆試:30分鐘。1.壓控振蕩器的英文縮寫。2.動態(tài)隨機(jī)存儲器的英文縮寫。3.選擇電阻時(shí)要考慮什么?4.單片機(jī)上電后沒有運(yùn)轉(zhuǎn),一方面要檢查什么?5.計(jì)算機(jī)的基本組成部分及其各自的作用。6.如何用D觸發(fā)器、與或非門組成二分頻電路?64.static有什么用途?(請至少說明兩種)答、1.限制變量的作用域(文獻(xiàn)級的)。2.設(shè)立變量的存儲域(全局?jǐn)?shù)據(jù)區(qū))。66.描述實(shí)時(shí)系統(tǒng)的基本特性?答:在特定期間內(nèi)完畢特定的任務(wù),實(shí)時(shí)性與可靠性。67.全局變量和局部變量在內(nèi)存中是否有區(qū)別?假如有,是什么區(qū)別?答、全局變量儲存在靜態(tài)數(shù)據(jù)區(qū),局部變量在堆棧中。68.什么是平衡二叉樹?答、左右子樹都是平衡二叉樹且左右子樹的深度差值的絕對值不大于1。69.堆棧溢出一般是由什么因素導(dǎo)致的?答:1.沒有回收垃圾資源 2.層次太深的遞歸調(diào)用?70.什么函數(shù)不能聲明為虛函數(shù)?答:constructor Deconstructor可以聲明為虛函數(shù)。 系統(tǒng)為一個(gè)空類創(chuàng)建的成員函數(shù)有那些。默認(rèn)構(gòu)造函數(shù)析構(gòu)函數(shù)拷貝構(gòu)造函數(shù)賦值運(yùn)算符(operator=)取址運(yùn)算符(operator&)(一對,一個(gè)非const的,一個(gè)const的)當(dāng)然,所有這些只有當(dāng)被需要才會產(chǎn)生。比如你定義了一個(gè)類,但歷來定義過該類的對象,也沒使用過該類型的函數(shù)參數(shù),那么基本啥也不會產(chǎn)生。在比如你歷來沒有進(jìn)行過該類型對象之間的賦值,那么operator=不會被產(chǎn)生。71.冒泡排序算法的時(shí)間復(fù)雜度是什么?答:O(n^2)72.寫出floatx與“零值”比較的if語句。答、if(x>0.000001&&x<-0.000001)73.Internet采用哪種網(wǎng)絡(luò)協(xié)議?該協(xié)議的重要層次結(jié)構(gòu)?答:tcp/ip應(yīng)用層/傳輸層/網(wǎng)絡(luò)層/數(shù)據(jù)鏈路層/物理層74.Internet物理地址和IP地址轉(zhuǎn)換采用什么協(xié)議?答、ARP(AddressResolutionProtocol)(地址解析協(xié)議)75.IP地址的編碼分為哪倆部分?答、IP地址由兩部分組成,網(wǎng)絡(luò)號和主機(jī)號。但是是要和“子網(wǎng)掩碼”按位與之后才干區(qū)分哪些是網(wǎng)絡(luò)位哪些是主機(jī)位。76.用戶輸入M,N值,從1至N開始順序循環(huán)數(shù)數(shù),每數(shù)到M輸出該數(shù)值,直至所有輸出。寫出C程序。答:循環(huán)鏈表,用取余操作做77.不能做switch()的參數(shù)類型是:答:switch的參數(shù)不能為實(shí)型。78.局部變量能否和全局變量重名?答:能,局部會屏蔽全局。要用全局變量,需要使用"::"局部變量可以與全局變量同名,在函數(shù)內(nèi)引用這個(gè)變量時(shí),會用到同名的局部變量,而不會用到全局變量。對于有些編譯器而言,在同一個(gè)函數(shù)內(nèi)可以定義多個(gè)同名的局部變量,比如在兩個(gè)循環(huán)體內(nèi)都定義一個(gè)同名的局部變量,而那個(gè)局部變量的作用域就在那個(gè)循環(huán)體內(nèi)79.如何引用一個(gè)已經(jīng)定義過的全局變量?答:可以用引用頭文獻(xiàn)的方式,也可以用extern關(guān)鍵字,假如用引用頭文獻(xiàn)方式來引用某個(gè)在頭文獻(xiàn)中聲明的全局變理,假定你將那個(gè)變量寫錯(cuò)了,那么在編譯期間會報(bào)錯(cuò),假如你用extern方式引用時(shí),假定你犯了同樣的錯(cuò)誤,那么在編譯期間不會報(bào)錯(cuò),而在連接期間報(bào)錯(cuò)80.全局變量可不可以定義在可被多個(gè).C文獻(xiàn)包含的頭文獻(xiàn)中?為什么?答:可以,在不同的C文獻(xiàn)中以static形式來聲明同名全局變量??梢栽诓煌腃文獻(xiàn)中聲明同名的全局變量,前提是其中只能有一個(gè)C文獻(xiàn)中對此變量賦初值,此時(shí)連接不會犯錯(cuò)81.語句for(;1;)有什么問題?它是什么意思?答:和while(1)相同。82.do……while和while……do有什么區(qū)別?答:前一個(gè)循環(huán)一遍再判斷,后一個(gè)判斷以后再循環(huán)83.請寫出下列代碼的輸出內(nèi)容答:10,12,120#includeintmain(){inta,b,c,d;a=10;b=a++;c=++a;d=10*a++;printf("b,c,d:%d,%d,%d",b,c,d);return0;}84.stat(yī)ac全局變量、局部變量、函數(shù)與普通全局變量、局部變量、函數(shù):static全局變量與普通的全局變量有什么區(qū)別?stat(yī)ic局部變量和普通局部變量有什么區(qū)別?static函數(shù)與普通函數(shù)有什么區(qū)別?答、全局變量(外部變量)的說明之前再冠以static就構(gòu)成了靜態(tài)的全局變量。全局變量自身就是靜態(tài)存儲方式,靜態(tài)全局變量當(dāng)然也是靜態(tài)存儲方式。這兩者在存儲方式上并無不同。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個(gè)源程序,當(dāng)一個(gè)源程序由多個(gè)源文獻(xiàn)組成時(shí),非靜態(tài)的全局變量在各個(gè)源文獻(xiàn)中都是有效的。而靜態(tài)全局變量則限制了其作用域,即只在定義該變量的源文獻(xiàn)內(nèi)有效,在同一源程序的其它源文獻(xiàn)中不能使用它。由于靜態(tài)全局變量的作用域局限于一個(gè)源文獻(xiàn)內(nèi),只能為該源文獻(xiàn)內(nèi)的函數(shù)公用,因此可以避免在其它源文獻(xiàn)中引起錯(cuò)誤。從以上分析可以看出,把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,限制了它的使用范圍。static函數(shù)與普通函數(shù)作用域不同。僅在本文獻(xiàn)。只在當(dāng)前源文獻(xiàn)中使用的函數(shù)應(yīng)當(dāng)說明為內(nèi)部函數(shù)(static),內(nèi)部函數(shù)應(yīng)當(dāng)在當(dāng)前源文獻(xiàn)中說明和定義。對于可在當(dāng)前源文獻(xiàn)以外使用的函數(shù),應(yīng)當(dāng)在一個(gè)頭文獻(xiàn)中說明,要使用這些函數(shù)的源文獻(xiàn)要包含這個(gè)頭文獻(xiàn)static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化一次,防止在其他文獻(xiàn)單元中被引用;static局部變量和普通局部變量有什么區(qū)別:static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;static函數(shù)與普通函數(shù)有什么區(qū)別:static函數(shù)在內(nèi)存中只有一份,普通函數(shù)在每個(gè)被調(diào)用中維持一份拷貝程序的局部變量存在于(堆棧)中,全局變量存在于(靜態(tài)區(qū))中,動態(tài)申請數(shù)據(jù)存在于(堆)中。85.設(shè)有以下說明和定義:typedefunion{longi;intk[5];charc;}DATE;structdat(yī)a{intcat(yī);DATEcow;doubledog;}too;DATEmax;則語句printf("%d",sizeof(structdate)+sizeof(max));的執(zhí)行結(jié)果是?答、結(jié)果是:___52__(dá)__(dá)。DATE是一個(gè)union,變量公用空間.里面最大的變量類型是int[5],占用20個(gè)字節(jié).所以它的大小是20。data是一個(gè)struct,每個(gè)變量分開占用空間.依次為int4+DATE20+double8=32.所以結(jié)果是20+32=52.當(dāng)然...在某些16位編輯器下,int也許是2字節(jié),那么結(jié)果是int2+DATE10+double8=2086.-1,2,7,28,,126請問28和126中間那個(gè)數(shù)是什么?為什么?答、應(yīng)當(dāng)是4^3-1=63規(guī)律是n^3-1(當(dāng)n為偶數(shù)0,2,4)n^3+1(當(dāng)n為奇數(shù)1,3,5)87.用兩個(gè)棧實(shí)現(xiàn)一個(gè)隊(duì)列的功能?規(guī)定給出算法和思緒!答、設(shè)2個(gè)棧為A,B,一開始均為空.入隊(duì):將新元素push入棧A;出隊(duì):(1)判斷棧B是否為空;(2)假如不為空,則將棧A中所有元素依次pop出并push到棧B;(3)將棧B的棧頂元素pop出;這樣實(shí)現(xiàn)的隊(duì)列入隊(duì)和出隊(duì)的平攤復(fù)雜度都還是O(1),比上面的幾種方法要好。88.在c語言庫函數(shù)中將一個(gè)字符轉(zhuǎn)換成整型的函數(shù)是atool()嗎,這個(gè)函數(shù)的原型是什么?答:函數(shù)名:atol功能:把字符串轉(zhuǎn)換成長整型數(shù)用法:longatol(constchar*nptr);程序例:#include#includeintmain(void){longl;char*str="98765432";l=atol(lstr);printf("string=%sinteger=%ld\n",str,l);return(0);}89.對于一個(gè)頻繁使用的短小函數(shù),在C語言中應(yīng)用什么實(shí)現(xiàn),在C++中應(yīng)用什么實(shí)現(xiàn)?答、c用宏定義,c++用inline90.用預(yù)解決指令#define聲明一個(gè)常數(shù),用以表白1年中有多少秒(忽略閏年問題)#defineSECONDS_PER_YEAR(60*60*24*365)UL我在這想看到幾件事情:1).#define語法的基本知識(例如:不能以分號結(jié)束,括號的使用,等等)2).懂得預(yù)解決器將為你計(jì)算常數(shù)表達(dá)式的值,因此,直接寫出你是如何計(jì)算一年中有多少秒而不是計(jì)算出實(shí)際的值,是更清楚而沒有代價(jià)的。3).意識到這個(gè)表達(dá)式將使一個(gè)16位機(jī)的整型數(shù)溢出-因此要用到長整型符號L,告訴編譯器這個(gè)常數(shù)是的長整型數(shù)。4).假如你在你的表達(dá)式中用到UL(表達(dá)無符號長整型),那么你有了一個(gè)好的起點(diǎn)。記住,第一印象很重要。91.寫一個(gè)“標(biāo)準(zhǔn)”宏MIN,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一個(gè)。#defineMIN(A,B)((A)<=(B)(A):(B))這個(gè)測試是為下面的目的而設(shè)的:1).標(biāo)記#define在宏中應(yīng)用的基本知識。這是很重要的,由于直到嵌入(inline)操作符變?yōu)闃?biāo)準(zhǔn)C的一部分,宏是方便產(chǎn)生嵌入代碼的唯一方法,對于嵌入式系統(tǒng)來說,為了能達(dá)成規(guī)定的性能,嵌入代碼經(jīng)常是必須的方法。2).三重條件操作符的知識。這個(gè)操作符存在C語言中的因素是它使得編譯器能產(chǎn)生比if-then-else更優(yōu)化的代碼,了解這個(gè)用法是很重要的。3).懂得在宏中小心地把參數(shù)用括號括起來4).我也用這個(gè)問題開始討論宏的副作用,例如:當(dāng)你寫下面的代碼時(shí)會發(fā)生什么事?least=MIN(*p++,b);92.預(yù)解決器標(biāo)記#error的目的是什么?假如你不知道答案,請看參考文獻(xiàn)1。這問題對區(qū)分一個(gè)正常的伙計(jì)和一個(gè)書呆子是很有用的。只有書呆子才會讀C語言課本的附錄去找出象這種問題的答案。當(dāng)然假如你不是在找一個(gè)書呆子,那么應(yīng)試者最佳希望自己不要知道答案。死循環(huán)(Infiniteloops)93.嵌入式系統(tǒng)中經(jīng)常要用到無限循環(huán),你怎么樣用C編寫死循環(huán)呢?這個(gè)問題用幾個(gè)解決方案。我首選的方案是:while(1){}一些程序員更喜歡如下方案:for(;1;){}這個(gè)實(shí)現(xiàn)方式讓我為難,由于這個(gè)語法沒有確切表達(dá)成底怎么回事。假如一個(gè)應(yīng)試者給出這個(gè)作為方案,我將用這個(gè)作為一個(gè)機(jī)會去探究他們這樣做的基本原理。假如他們的基本答案是:“我被教著這樣做,但從沒有想到過為什么?!边@會給我留下一個(gè)壞印象。第三個(gè)方案是用gotoLoop:...gotoL(fēng)oop;應(yīng)試者如給出上面的方案,這說明或者他是一個(gè)匯編語言程序員(這也許是好事)或者他是一個(gè)想進(jìn)入新領(lǐng)域的BASIC/FORTRAN程序員。數(shù)據(jù)聲明(Datadeclarations)94.用變量a給出下面的定義a)一個(gè)整型數(shù)(Aninteger)b)一個(gè)指向整型數(shù)的指針(Apointertoaninteger)c)一個(gè)指向指針的的指針,它指向的指針是指向一個(gè)整型數(shù)(Apointertoapointertoaninteger)d)一個(gè)有10個(gè)整型數(shù)的數(shù)組(Anarrayof10integers)e)一個(gè)有10個(gè)指針的數(shù)組,該指針是指向一個(gè)整型數(shù)的(Anarrayof10pointerstointegers)f)一個(gè)指向有10個(gè)整型數(shù)數(shù)組的指針(Apointertoanarrayof10integers)g)一個(gè)指向函數(shù)的指針,該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger)h)一個(gè)有10個(gè)指針的數(shù)組,該指針指向一個(gè)函數(shù),該函數(shù)有一個(gè)整型參數(shù)并返回一個(gè)整型數(shù)(Anarrayoftenpointerstofunctionsthattakeanintegerargumentandreturnaninteger)答案是:a)inta;//Anintegerb)int*a;//Apointertoanintegerc)int**a;//Apointertoapointertoanintegerd)inta[10];//Anarrayof10integerse)int*a[10];//Anarrayof10pointerstointegersf)int(*a)[10];//Apointertoanarrayof10integersg)int(*a)(int);//Apointertoafunctionathattakesanintegerargumentandreturnsanintegerh)int(*a[10])(int);//Anarrayof10pointerstofunctionsthattakeanintegerargumentandreturnanintegerStatic95.關(guān)鍵字static的作用是什么?在C語言中,關(guān)鍵字static有三個(gè)明顯的作用:1).在函數(shù)體,一個(gè)被聲明為靜態(tài)的變量在這一函數(shù)被調(diào)用過程中維持其值不變。2).在模塊內(nèi)(但在函數(shù)體外),一個(gè)被聲明為靜態(tài)的變量可以被模塊內(nèi)所用函數(shù)訪問,但不能被模塊外其它函數(shù)訪問。它是一個(gè)本地的全局變量。3).在模塊內(nèi),一個(gè)被聲明為靜態(tài)的函數(shù)只可被這一模塊內(nèi)的其它函數(shù)調(diào)用。那就是,這個(gè)函數(shù)被限制在聲明它的模塊的本地范圍內(nèi)使用。Const96.關(guān)鍵字const是什么含意?我只要一聽到被面試者說:“const意味著常數(shù)”,我就知道我正在和一個(gè)業(yè)余者打交道。去年DanSaks已經(jīng)在他的文章里完全概括了const的所有用法,因此ESP(譯者:EmbeddedSystemsProgramming)的每一位讀者應(yīng)當(dāng)非常熟悉const能做什么和不能做什么.假如你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。盡管這個(gè)答案不是完全的答案,但我接受它作為一個(gè)對的的答案。(假如你想知道更具體的答案,仔細(xì)讀一下Saks的文章吧。)假如應(yīng)試者能對的回答這個(gè)問題,我將問他一個(gè)附加的問題:下面的聲明都是什么意思?constinta;intconsta;constint*a;int*consta;intconst*aconst;前兩個(gè)的作用是同樣,a是一個(gè)常整型數(shù)。第三個(gè)意味著a是一個(gè)指向常整型數(shù)的指針(也就是,整型數(shù)是不可修改的,但指針可以)。第四個(gè)意思a是一個(gè)指向整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是可以修改的,但指針是不可修改的)。最后一個(gè)意味著a是一個(gè)指向常整型數(shù)的常指針(也就是說,指針指向的整型數(shù)是不可修改的,同時(shí)指針也是不可修改的)。假如應(yīng)試者能對的回答這些問題,那么他就給我留下了一個(gè)好印象。順帶提一句,也許你也許會問,即使不用關(guān)鍵字const,也還是能很容易寫出功能對的的程序,那么我為什么還要如此看重關(guān)鍵字const呢?我也如下的幾下理由:1).關(guān)鍵字const的作用是為給讀你代碼的人傳達(dá)非常有用的信息,事實(shí)上,聲明一個(gè)參數(shù)為常量是為了告訴了用戶這個(gè)參數(shù)的應(yīng)用目的。假如你曾花很多時(shí)間清理其它人留下的垃圾,你就會不久學(xué)會感謝這點(diǎn)多余的信息。(當(dāng)然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)2).通過給優(yōu)化器一些附加的信息,使用關(guān)鍵字const也許能產(chǎn)生更緊湊的代碼。3).合理地使用關(guān)鍵字const可以使編譯器很自然地保護(hù)那些不希望被改變的參數(shù),防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現(xiàn)。Volatile97.關(guān)鍵字volatile有什么含意并給出三個(gè)不同的例子。一個(gè)定義為volatile的變量是說這變量也許會被意想不到地改變,這樣,編譯器就不會去假設(shè)這個(gè)變量的值了。精確地說就是,優(yōu)化器在用到這個(gè)變量時(shí)必須每次都小心地重新讀取這個(gè)變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個(gè)例子:1).并行設(shè)備的硬件寄存器(如:狀態(tài)寄存器)2).一個(gè)中斷服務(wù)子程序中會訪問到的非自動變量(Non-automat(yī)icvariables)3).多線程應(yīng)用中被幾個(gè)任務(wù)共享的變量回答不出這個(gè)問題的人是不會被雇傭的。我認(rèn)為這是區(qū)分C程序員和嵌入式系統(tǒng)程序員的最基本的問題。嵌入式系統(tǒng)程序員經(jīng)常同硬件、中斷、RTOS等等打交道,所用這些都規(guī)定volatile變量。不懂得volat(yī)ile內(nèi)容將會帶來劫難。假設(shè)被面試者對的地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。1).一個(gè)參數(shù)既可以是const還可以是volatile嗎?解釋為什么。2).一個(gè)指針可以是volatile嗎?解釋為什么。3).下面的函數(shù)有什么錯(cuò)誤:intsquare(volatileint*ptr){return*ptr**ptr;}下面是答案:1).是的。一個(gè)例子是只讀的狀態(tài)寄存器。它是volatile由于它也許被意想不到地改變。它是const由于程序不應(yīng)當(dāng)試圖去修改它。2).是的。盡管這并不很常見。一個(gè)例子是當(dāng)一個(gè)中服務(wù)子程序修該一個(gè)指向一個(gè)buffer的指針時(shí)。3).這段代碼的有個(gè)惡作劇。這段代碼的目的是用來返指針*ptr指向值的平方,但是,由于*ptr指向一個(gè)volat(yī)ile型參數(shù),編譯器將產(chǎn)生類似下面的代碼:intsquare(volat(yī)ileint*ptr){inta,b;a=*ptr;b=*ptr;returna*b;}由于*ptr的值也許被意想不到地該變,因此a和b也許是不同的。結(jié)果,這段代碼也許返不是你所盼望的平方值!對的的代碼如下:longsquare(volatileint*ptr){inta;a=*ptr;returna*a;}位操作(Bitmanipulation)98.下面的代碼輸出是什么,為什么?voidfoo(void){unsignedinta=6;intb=-20;(a+b>6)puts(">6"):puts("<=6");}這個(gè)問題測試你是否懂得C語言中的整數(shù)自動轉(zhuǎn)換原則,我發(fā)現(xiàn)有些開發(fā)者懂得很少這些東西。不管如何,這無符號整型問題的答案是輸出是“>6”。因素是當(dāng)表達(dá)式中存在有符號類型和無符號類型時(shí)所有的操作數(shù)都自動轉(zhuǎn)換為無符號類型。因此-20變成了一個(gè)非常大的正整數(shù),所以該表達(dá)式計(jì)算出的結(jié)果大于6。這一點(diǎn)對于應(yīng)當(dāng)頻繁用到無符號數(shù)據(jù)類型的嵌入式系統(tǒng)來說是豐常重要的。假如你答錯(cuò)了這個(gè)問題,你也就到了得不到這份工作的邊沿。99.C語言批準(zhǔn)一些令人震驚的結(jié)構(gòu),下面的結(jié)構(gòu)是合法的嗎,假如是它做些什么?inta=5,b=7,c;c=a+++b;這個(gè)問題將做為這個(gè)測驗(yàn)的一個(gè)快樂的結(jié)尾。不管你相不相信,上面的例子是完全合乎語法的。問題是編譯器如何解決它?水平不高的編譯作者事實(shí)上會爭論這個(gè)問題,根據(jù)最解決原則,編譯器應(yīng)當(dāng)能解決盡也許所有合法的用法。因此,上面的代碼被解決成:c=a+++b;因此,這段代碼持行后a=6,b=7,c=12。假如你知道答案,或猜出對的答案,做得好。假如你不知道答案,我也不把這個(gè)當(dāng)作問題。我發(fā)現(xiàn)這個(gè)問題的最大好處是:這是一個(gè)關(guān)于代碼編寫風(fēng)格,代碼的可讀性,代碼的可修改性的好的話題,100.線形表a、b為兩個(gè)有序升序的線形表,編寫一程序,使兩個(gè)有序線形表合并成一個(gè)有序升序線形表h;答案在請化大學(xué)嚴(yán)銳敏《數(shù)據(jù)結(jié)構(gòu)第二版》第二章例題,數(shù)據(jù)結(jié)構(gòu)當(dāng)中,這個(gè)叫做:兩路歸并排序Linklist*unio(Linklist*p,Linklist*q){linklist*R,*pa,*qa,*ra;pa=p;qa=q;R=ra=p;while(pa->next!=NULL&&qa->next!=NULL){if(pa->data>qa->data){ra->next=qa;qa=qa->next;}else{ra->next=pa;pa=pa->next;}}if(pa->next?。絅ULL)ra->next=pa;if(qa->next!=NULL)ra->next==qa;returnR;}101.用遞歸算法判斷數(shù)組a[N]是否為一個(gè)遞增數(shù)組。遞歸的方法,記錄當(dāng)前最大的,并且判斷當(dāng)前的是否比這個(gè)還大,大則繼續(xù),否則返回false結(jié)束:boolfun(inta[],intn){if(n==1
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山東省濟(jì)寧市泗水縣2023-2024學(xué)年八年級上學(xué)期期末英語試題(解析版)-A4
- 2023年硝基復(fù)合肥項(xiàng)目籌資方案
- 2023年氰化物中毒解毒藥項(xiàng)目籌資方案
- 《氟斑牙DEAN氏診斷》課件
- 2023年人工種植牙項(xiàng)目融資計(jì)劃書
- 《電機(jī)與拖動復(fù)習(xí)》課件
- 養(yǎng)老院老人心理咨詢師表彰制度
- 養(yǎng)老院老人精神關(guān)懷制度
- 《的工作方式》課件
- 《王老吉SWOT分析新》課件
- 八年級親子共評
- 國開電大行管本科《城市管理學(xué)》期末考試考試總題庫2024珍藏版
- 父親的露珠-閱讀附答案(2019浙江紹興中考試題)-記敘文閱讀及答案
- 精裝房裝修開發(fā)營銷策劃
- 培養(yǎng)孩子的品德與人格塑造
- 《售后提升滿意度》課件
- 六年級數(shù)學(xué)上冊學(xué)業(yè)質(zhì)量評價(jià)方案
- 《項(xiàng)目交付管理》課件
- 一年級體育教案跳繩完整版
- 山東省青島地區(qū)2023-2024學(xué)年四年級上學(xué)期1月期末科學(xué)試題
- 金屬冶煉安全職業(yè)病防治與健康管理
評論
0/150
提交評論