




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1.new、delete、malloc、free關系delete會調用對象的析構函數,和new相應free只會釋放內存,new調用構造函數。malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用于申請動態內存和釋放內存。對于非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的規定。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由于malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不可以把執行構造函數和析構函數的任務強加于malloc/free。因此C++語言需要一個能完畢動態內存分派和初始化工作的運算符new,以及一個能完畢清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。2.delete與delete[]區別?delete只會調用一次析構函數,而delete[]會調用每一個成員的析構函數。在MoreEffectiveC++中有更為具體的解釋:“當delete操作符用于數組時,它為每個數組元素調用析構函數,然后調用operatordelete來釋放內存。”delete與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-處報錯。這就說明:對于內建簡樸數據類型,delete和delete[]功能是相同的。對于自定義的復雜數據類型,delete和delete[]不能互用。delete[]刪除一個數組,delete刪除一個指針簡樸來說,用new分派的內存用delete刪除用new[]分派的內存用delete[]刪除delete[]會調用數組元素的析構函數。內部數據類型沒有析構函數,所以問題不大。假如你在用delete時沒用括號,delete就會認為指向的是單個對象,否則,它就會認為指向的是一個數組。3.CC++JAVA共同點,不同之處?4.繼承優缺陷。類繼承是在編譯時刻靜態定義的,且可直接使用,類繼承可以較方便地改變父類的實現。但是類繼承也有一些局限性之處。一方面,由于繼承在編譯時刻就定義了,所以無法在運營時刻改變從父類繼承的實現。更糟的是,父類通常至少定義了子類的部分行為,父類的任何改變都也許影響子類的行為。假如繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關系限制了靈活性并最終限制了復用性。(待補充)5.C++有哪些性質(面向對象特點)?封裝,繼承和多態。在面向對象程序設計語言中,封裝是運用可重用成分構造軟件系統的特性,它不僅支持系統的可重用性,并且尚有助于提高系統的可擴充性;消息傳遞可以實現發送一個通用的消息而調用不同的方法;封裝是實現信息隱蔽的一種技術,其目的是使類的定義和實現分離。6.子類析構時要調用父類的析構函數嗎?析構函數調用的順序是先派生類的析構后基類的析構,也就是說在基類的的析構調用的時候,派生類的信息已經所有銷毀了。定義一個對象時先調用基類的構造函數、然后調用派生類的構造函數;析構的時候恰好相反:先調用派生類的析構函數、然后調用基類的析構函數JAVA無析構函數深拷貝和淺拷貝7.多態,虛函數,純虛函數8.求下面函數的返回值(微軟)intfunc(x)
{?
intcountx=0;
while(x)?
{?
countx++;?
x=x&(x-1);
}?
returncountx;?}
假定x=9999。答案:8。思緒:將x轉化為2進制,看具有的1的個數。9.什么是“引用”?申明和使用“引用”要注意哪些問題?答:引用就是某個目的變量的“別名”(alias),對引用的操作與對變量直接操作效果完全相同。申明一個引用的時候,牢記要對其進行初始化。引用聲明完畢后,相稱于目的變量名有兩個名稱,即該目的原名稱和引用名,不能再把該引用名作為其他變量名的別名。聲明一個引用,不是新定義了一個變量,它只表達該引用名是目的變量名的一個別名,它自身不是一種數據類型,因此引用自身不占存儲單元,系統也不給引用分派存儲單元。不能建立數組的引用。10.將“引用”作為函數參數有哪些特點?(1)傳遞引用給函數與傳遞指針的效果是同樣的。這時,被調函數的形參就成為本來主調函數中的實參變量或對象的一個別名來使用,所以在被調函數中對形參變量的操作就是對其相應的目的對象(在主調函數中)的操作。(2)使用引用傳遞函數的參數,在內存中并沒有產生實參的副本,它是直接對實參操作;而使用一般變量傳遞函數的參數,當發生函數調用時,需要給形參分派存儲單元,形參變量是實參變量的副本;假如傳遞的是對象,還將調用拷貝構造函數。因此,當參數傳遞的數據較大時,用引用比用一般變量傳遞參數的效率和所占空間都好。(3)使用指針作為函數的參數雖然也能達成與使用引用的效果,但是,在被調函數中同樣要給形參分派存儲單元,且需要反復使用"*指針變量名"的形式進行運算,這很容易產生錯誤且程序的閱讀性較差;另一方面,在主調函數的調用點處,必須用變量的地址作為實參。而引用更容易使用,更清楚。11.在什么時候需要使用“常引用”?假如既要運用引用提高程序的效率,又要保護傳遞給函數的數據不在函數中被改變,就應使用常引用。常引用聲明方式:const類型標記符&引用名=目的變量名;例1inta;constint&ra=a;ra=1;//錯誤a=1;//對的例2stringfoo();voidbar(string&s);那么下面的表達式將是非法的:bar(foo());bar("helloworld");因素在于foo()和"helloworld"串都會產生一個臨時對象,而在C++中,這些臨時對象都是const類型的。因此上面的表達式就是試圖將一個const類型的對象轉換為非const類型,這是非法的。引用型參數應當在能被定義為const的情況下,盡量定義為const。12.將“引用”作為函數返回值類型的格式、好處和需要遵守的規則?格式:類型標記符&函數名(形參列表及類型說明){//函數體}好處:在內存中不產生被返回值的副本;(注意:正是由于這點因素,所以返回一個局部變量的引用是不可取的。由于隨著該局部變量生存期的結束,相應的引用也會失效,產生runtimeerror!注意事項:(1)不能返回局部變量的引用。這條可以參照EffectiveC++[1]的Item31。重要因素是局部變量會在函數返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進入未知狀態。(2)不能返回函數內部new分派的內存的引用。這條可以參照EffectiveC++[1]的Item31。雖然不存在局部變量的被動銷毀問題,可對于這種情況(返回函數內部new分派內存的引用),又面臨其它尷尬局面。例如,被函數返回的引用只是作為一個臨時變量出現,而沒有被賦予一個實際的變量,那么這個引用所指向的空間(由new分派)就無法釋放,導致memoryleak。(3)可以返回類成員的引用,但最佳是const。這條原則可以參照EffectiveC++[1]的Item30。重要因素是當對象的屬性是與某種業務規則(businessrule)相關聯的時候,其賦值經常與某些其它屬性或者對象的狀態有關,因此有必要將賦值操作封裝在一個業務規則當中。假如其它對象可以獲得該屬性的非常量引用(或指針),那么對該屬性的單純賦值就會破壞業務規則的完整性。(4)流操作符重載返回值申明為“引用”的作用:流操作符<<和>>,這兩個操作符經常希望被連續使用,例如:cout<<"hello"<<endl;因此這兩個操作符的返回值應當是一個仍然支持這兩個操作符的流引用。可選的其它方案涉及:返回一個流對象和返回一個流對象指針。但是對于返回一個流對象,程序必須重新(拷貝)構造一個新的流對象,也就是說,連續的兩個<<操作符事實上是針對不同對象的!這無法讓人接受。對于返回一個流指針則不能連續使用<<操作符。因此,返回一個流對象引用是惟一選擇。這個唯一選擇很關鍵,它說明了引用的重要性以及無可替代性,也許這就是C++語言中引入引用這個概念的因素吧。賦值操作符=。這個操作符象流操作符同樣,是可以連續使用的,例如:x=j=10;或者(x=10)=100;賦值操作符的返回值必須是一個左值,以便可以被繼續賦值。因此引用成了這個操作符的惟一返回值選擇。例3#include<iostream.h>
int&put(intn);?intvals[10];?interror=-1;?voidmain()?{
put(0)=10;//以put(0)函數值作為左值,等價于vals[0]=10;?put(9)=20;//以put(9)函數值作為左值,等價于vals[9]=20;?cout<<vals[0];
cout<<vals[9];?}?int&put(intn)
{
if(n>=0&&n<=9)returnvals[n];
else{cout<<"subscripterror";returnerror;}?}(5)在此外的一些操作符中,卻千萬不能返回引用:+-*/四則運算符。它們不能返回引用,EffectiveC++[1]的Item23具體的討論了這個問題。重要因素是這四個操作符沒有sideeffect,因此,它們必須構造一個對象作為返回值,可選的方案涉及:返回一個對象、返回一個局部變量的引用,返回一個new分派的對象的引用、返回一個靜態對象引用。根據前面提到的引用作為返回值的三個規則,第2、3兩個方案都被否決了。靜態對象的引用又由于((a+b)==(c+d))會永遠為true而導致錯誤。所以可選的只剩下返回一個對象了。13.“引用”與多態的關系?引用是除指針外另一個可以產生多態效果的手段。這意味著,一個基類的引用可以指向它的派生類實例。例4ClassA;ClassB:ClassA{...};
Bb;A&ref=b;14.“引用”與指針的區別是什么?1)引用必須被初始化,指針不必。2)引用初始化以后不能被改變,指針可以改變所指的對象。2)不存在指向空值的引用,但是存在指向空值的指針。指針通過某個指針變量指向一個對象后,對它所指向的變量間接操作。程序中使用指針,程序的可讀性差;而引用自身就是目的變量的別名,對引用的操作就是對目的變量的操作。此外,就是上面提到的對函數傳ref和pointer的區別。15.什么時候需要“引用”?流操作符<<和>>、賦值操作符=的返回值、拷貝構造函數的參數、賦值操作符=的參數、其它情況都推薦使用引用。以上2-8參考:16.結構與聯合有和區別?(1).結構和聯合都是由多個不同的數據類型成員組成,但在任何同一時刻,聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間),而結構的所有成員都存在(不同成員的存放地址不同)。
?
(2).對于聯合的不同成員賦值,將會對其它成員重寫,
本來成員的值就不存在了,而對于結構的不同成員賦值是互不影響的。17.面關于“聯合”的題目的輸出?a)#include<stdio.h>
union?{
inti;
charx[2];
}a;void
main()?{?a.x[0]=10;?a.x[1]=1;
printf("%d",a.i);?}?答案:266(低位低地址,高位高地址,內存占用情況是Ox010A)b)main()?
{?
union{
/*定義一個聯合*/
inti;?
struct{
/*在聯合中定義一個結構*/?
charfirst;?
charsecond;?
}half;
}number;
number.i=0x4241;
/*聯合成員賦值*/?
printf("%c%cn",number.half.first,mumber.half.second);
number.half.first='a';
/*聯合中結構成員賦值*/
number.half.second='b';
printf("%xn",number.i);?
getch();?
}
答案:AB
(0x41相應'A',是低位;Ox42相應'B',是高位)
6261(number.i和number.half共用一塊地址空間)18.關聯、聚合(Aggregation)以及組合(Composition)的區別?涉及到UML中的一些概念:關聯是表達兩個類的一般性聯系,比如“學生”和“老師”就是一種關聯關系;聚合表達has-a的關系,是一種相對松散的關系,聚合類不需要對被聚合類負責,如下圖所示,用空的菱形表達聚合關系:從實現的角度講,聚合可以表達為:classA{...}
classB{A*a;.....}而組合表達contains-a的關系,關聯性強于聚合:組合類與被組合類有相同的生命周期,組合類要對被組合類負責,采用實心的菱形表達組合關系:實現的形式是:classA{...}classB{Aa;...}27.
main函數執行以前,還會執行什么代碼?答案:全局對象的構造函數會在main函數之前執行。28.
描述內存分派方式以及它們的區別?1)從靜態存儲區域分派。內存在程序編譯時就已經分派好,這塊內存在程序的整個運營期間都存在。例如全局變量,static變量。
2)在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分派運算內置于解決器的指令集。
3)從堆上分派,亦稱動態內存分派。程序在運營時用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存期由程序員決定,使用非常靈活,但問題也最多。29.struct和class的區別答案:struct的成員默認是公有的,而類的成員默認是私有的。struct和class在其他方面是功能相稱的。從感情上講,大多數的開發者感到類和結構有很大的差別。感覺上結構僅僅象一堆缺少封裝和功能的開放的內存位,而類就象活的并且可靠的社會成員,它有智能服務,有牢固的封裝屏障和一個良好定義的接口。既然大多數人都這么認為,那么只有在你的類有很少的方法并且有公有數據(這種事情在良好設計的系統中是存在的!)時,你也許應當使用struct關鍵字,否則,你應當使用class關鍵字。
30.當一個類A中沒有任何成員變量與成員函數,這時sizeof(A)的值是多少?答案:假如不是零,請解釋一下編譯器為什么沒有讓它為零。(Autodesk)肯定不是零。舉個反例,假如是零的話,聲明一個classA[10]對象數組,而每一個對象占用的空間是零,這時就沒辦法區分A[0],A[1]…了。值為1.32.
比較C++中的4種類型轉換方式?請參考:,重點是static_cast,dynamic_cast和reinterpret_cast的區別和應用。dynamic_casts在幫助你瀏覽繼承層次上是有限制的。它不能被用于缺少虛函數的類型上,它被用于安全地沿著類的繼承關系向下進行類型轉換。如你想在沒有繼承關系的類型中進行轉換,你也許想到static_cast44.寫一個在一個字符串(n)中尋找一個子串(m)第一個位置的函數。KMP算法效率最佳,時間復雜度是O(n+m),詳見:48.指針找錯題?分析這些面試題,自身包含很強的趣味性;而作為一名研發人員,通過對這些面試題的進一步剖析則可進一步增強自身的內功。?2.找錯題試題1:
以下是引用片段:
voidtest1()//數組越界
{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個字節才干存放下(涉及末尾的’\0’),而string只有10個字節的空間,strcpy會導致數組越界;試題2,假如面試者指出字符數組str1不能在數組內結束可以給3分;假如面試者指出strcpy(string,str1)調用使得從str1內存起復制到string內存起所復制的字節數具有不擬定性可以給7分,在此基礎上指出庫函數strcpy工作方式的給10分;?對試題3,if(strlen(str1)<=10)應改為if(strlen(str1)<10),由于strlen的結果未記錄’\0’所占用的1個字節。剖析:考核對基本功的掌握(1)字符串以’\0’結尾;(2)對數組越界把握的敏感度;(3)庫函數strcpy的工作方式,49.假如編寫一個標準strcpy函數?總分值為10,下面給出幾個不同得分的答案:2分以下是引用片段:
voidstrcpy(char*strDest,char*strSrc)
{?while((*strDest++=*strSrc++)!=‘\0’);
}
4分以下是引用片段:
voidstrcpy(char*strDest,constchar*strSrc)?//將源字符串加const,表白其為輸入參數,加2分
{while((*strDest++=*strSrc++)!=‘\0’);}?7分以下是引用片段:?voidstrcpy(char*strDest,constchar*strSrc)
{//對源地址和目的地址加非0斷言,加3分
assert((strDest!=NULL)&&(strSrc!=NULL));
while((*strDest++=*strSrc++)!=‘\0’);}
10分以下是引用片段://為了實現鏈式操作,將目的地址返回,加3分!?char*strcpy(char*strDest,constchar*strSrc)?{assert((strDest!=NULL)&&(strSrc!=NULL));//對源地址和目的地址加非0斷言?char*address=strDest;
while((*strDest++=*strSrc++)!=‘\0’);?returnaddress;//為了實現鏈式操作,將目的地址返回}從2分到10分的幾個答案我們可以清楚的看到,小小的strcpy居然暗藏著這么多玄機,真不是蓋的!需要多么扎實的基本功才干寫一個完美的strcpy啊!
(4)對strlen的掌握,它沒有涉及字符串末尾的'\0'。讀者看了不同分值的strcpy版本,應當也可以寫出一個10分的strlen函數了,intstrlen(constchar*str)//輸入參數const以下是引用片段:
{
assert(strt!=NULL);//斷言字符串地址非0
intlen=0;//注,一定要初始化。?while((*str++)!='\0')?{len++;}?returnlen;?}?試題4:以下是引用片段:
voidGetMemory(char*p)//內存分派
{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)函數的形參為字符串指針,在函數內部修改形參并不能真正的改變傳入形參的值,執行完char*str=NULL;GetMemory(str);后的str仍然為NULL;試題5中charp[]="helloworld";returnp;的p[]數組為函數內的局部自動變量,在函數返回后,內存已經被釋放。這是許多程序員常犯的錯誤,其根源在于不理解變量的生存期。試題6的GetMemory避免了試題4的問題,傳入GetMemory的參數為字符串指針的指針,但是在GetMemory中執行申請內存及賦值語句*p=(char*)malloc(num);后未判斷內存是否申請成功,應加上:if(*p==NULL){...//進行申請內存失敗解決}?試題7存在與試題6同樣的問題,在執行char*str=(char*)malloc(100);后未進行內存是否申請成功的判斷;此外,在free(str)后未置str為空,導致也許變成一個“野”指針,應加上:str=NULL;試題6的Test函數中也未對malloc的內存進行釋放。
剖析:試題4~7考察面試者對內存操作的理解限度,基本功扎實的面試者一般都能對的的回答其中50~60的錯誤。但是要完全解答對的,卻也絕非易事。對內存操作的考察重要集中在:(1)指針的理解;(2)變量的生存期及作用范圍;(3)良好的動態內存申請和釋放習慣。
再看看下面的一段程序有什么錯誤:?以下是引用片段:?swap(int*p1,int*p2)?{int*p;?*p=*p1;
*p1=*p2;?*p2=*p;}
在swap函數中,p是一個“野”指針,有也許指向系統區,導致程序運營的崩潰。在VC++中DEBUG運營時提醒錯誤“AccessViolation”。該程序應當改為?以下是引用片段:
swap(int*p1,int*p2)
{intp;
p=*p1;?*p1=*p2;
*p2=p;}51.h頭文獻中的ifndef/define/endif的作用?答:防止該頭文獻被反復引用。52.#include<file.h>與#include"file.h"的區別?答:前者是從StandardLibrary的途徑尋找和引用file.h,而后者是從當前工作途徑搜尋并引用file.h。?53.在C++程序中調用被C編譯器編譯后的函數,為什么要加extern“C”?C++語言支持函數重載,C語言不支持函數重載。C++提供了C連接互換指定符號extern“C”解決名字匹配問題。一方面,作為extern是C/C++語言中表白函數和全局變量作用范圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量可以在本模塊或其它模塊中使用。通常,在模塊的頭文獻中對本模塊提供應其它模塊引用的函數和全局變量以關鍵字extern聲明。例如,假如模塊B欲引用該模塊A中定義的全局變量和函數時只需包含模塊A的頭文獻即可。這樣,模塊B中調用模塊A中的函數時,在編譯階段,模塊B雖然找不到該函數,但是并不會報錯;它會在連接階段中從模塊A編譯生成的目的代碼中找到此函數。extern"C"是連接申明(linkagedeclaration),被extern"C"修飾的變量和函數是按照C語言方式編譯和連接的,來看看C++中對類似C的函數是如何編譯的:作為一種面向對象的語言,C++支持函數重載,而過程式語言C則不支持。函數被C++編譯后在符號庫中的名字與C語言的不同。例如,假設某個函數的原型為:voidfoo(intx,inty);該函數被C編譯器編譯后在符號庫中的名字為_foo,而C++編譯器則會產生像_foo_int_int之類的名字(不同的編譯器也許生成的名字不同,但是都采用了相同的機制,生成的新名字稱為“mangledname”)。_foo_int_int這樣的名字包含了函數名、函數參數數量及類型信息,C++就是靠這種機制來實現函數重載的。例如,在C++中,函數voidfoo(intx,inty)與voidfoo(intx,floaty)編譯生成的符號是不相同的,后者為_foo_int_float。同樣地,C++中的變量除支持局部變量外,還支持類成員變量和全局變量。用戶所編寫程序的類成員變量也許與全局變量同名,我們以"."來區分。而本質上,編譯器在進行編譯時,與函數的解決相似,也為類中的變量取了一個獨一無二的名字,這個名字與用戶程序中同名的全局變量名字不同。未加extern"C"聲明時的連接方式假設在C++中,模塊A的頭文獻如下:?//模塊A頭文獻moduleA.h
#ifndefMODULE_A_H?#defineMODULE_A_H?intfoo(intx,inty);
#endif在模塊B中引用該函數:?//模塊B實現文獻moduleB.cpp
#include"moduleA.h"
foo(2,3);加extern"C"聲明后的編譯和連接方式加extern"C"聲明后,模塊A的頭文獻變為:?//模塊A頭文獻moduleA.h?#ifndefMODULE_A_H?#defineMODULE_A_H
extern"C"intfoo(intx,inty);?#endif在模塊B的實現文獻中仍然調用foo(2,3),其結果是:
(1)模塊A編譯生成foo的目的代碼時,沒有對其名字進行特殊解決,采用了C語言的方式;(2)連接器在為模塊B的目的代碼尋找foo(2,3)調用時,尋找的是未經修改的符號名_foo。假如在模塊A中函數聲明了foo為extern"C"類型,而模塊B中包含的是externintfoo(intx,inty),則模塊B找不到模塊A中的函數;反之亦然。所以,可以用一句話概括extern“C”這個聲明的真實目的(任何語言中的任何語法特性的誕生都不是隨意而為的,來源于真實世界的需求驅動。我們在思考問題時,不能只停留在這個語言是怎么做的,還要問一問它為什么要這么做,動機是什么,這樣我們可以更進一步地理解許多問題):實現C++與C及其它語言的混合編程。明白了C++中extern"C"的設立動機,我們下面來具體分析extern"C"通常的使用技巧:
extern"C"的慣用法1)在C++中引用C語言中的函數和變量,在包含C語言頭文獻(假設為cExample.h)時,需進行下列解決:extern"C"?{?#include"cExample.h"?}而在C語言的頭文獻中,對其外部函數只能指定為extern類型,C語言中不支持extern"C"聲明,在.c文獻中包含了extern"C"時會出現編譯語法錯誤。?C++引用C函數例子工程中包含的三個文獻的源代碼如下:
/*c語言頭文獻:cExample.h*/
#ifndefC_EXAMPLE_H
#defineC_EXAMPLE_H
externintadd(intx,inty);
#endif
/*c語言實現文獻:cExample.c*/?#include"cExample.h"?intadd(intx,inty)
{
returnx+y;?}
//c++實現文獻,調用add:cppFile.cpp
extern"C"
{#include"cExample.h"?}?intmain(intargc,char*argv[])
{add(2,3);
return0;?}假如C++調用一個C語言編寫的.DLL時,當涉及.DLL的頭文獻或聲明接口函數時,應加extern"C"{}。(2)在C中引用C++語言中的函數和變量時,C++的頭文獻需添加extern"C",但是在C語言中不能直接引用聲明了extern"C"的該頭文獻,應當僅將C文獻中將C++中定義的extern"C"函數聲明為extern類型。?C引用C++函數例子工程中包含的三個文獻的源代碼如下:
//C++頭文獻cppExample.h
#ifndefCPP_EXAMPLE_H
#defineCPP_EXAMPLE_H?extern"C"intadd(intx,inty);?#endif?//C++實現文獻cppExample.cpp?#include"cppExample.h"
intadd(intx,inty)?{
returnx+y;?}?/*C實現文獻cFile.c
/*這樣會編譯犯錯:#include"cExample.h"*/intmain(intargc,char*argv[])
{
add(2,3);?return0;?}15題目的解答請參考《C++中extern“C”含義深層探索》注解:幾道c筆試題(含參考答案)?1.Whatisdisplayedwhenf()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類型的構造函數被生命被explicit,也就是只能顯示類型轉換,不能使用隱式類型轉換
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。第二個選A;?第一個是指針加減,按照的是指向地址類型的加減,只跟類型位置有關,q和p指向的數據類型以實際數據類型來算差一個位置,因此是1。而第二個加減是實際指針值得加減,在內存中一個double類型占據8個字節,因此是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.完畢程序,實現對數組的降序排序
#include
voidsort();?intmain()
{?intarray[]={45,56,76,234,1,34,23,2,3};//數字任//意給出
sort();?return0;?}?voidsort()?{
____________________________________
||?||?|-----------------------------------------------------|?}
3.費波那其數列,1,1,2,3,5……編寫程序求第十項。可以用遞歸,也可以用其?他方法,但要說明你選擇的理由。
#include<iostream>usingnamespacestd;intPheponatch(int);intmain(){ cout<<"The10this"<<Pheponatch(10)<<endl;?return0;}intPheponatch(inti){?if(i==1||i==2) return1;?else? returnPheponatch(i-1)+Pheponatch(i-2);}4.下列程序運營時會崩潰,請找犯錯誤并改正,并且說明因素。
#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,數字任意給出?}?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的七層網絡結構圖和TCP/IP的五層結構圖。應用層:為應用程序提供服務表達層:解決在兩個通信系統中互換信息的表達方式會話層:負責維護兩個結點間會話連接的建立、管理和終止,以及數據互換傳輸層:向用戶提供可靠的端到端服務。UDPTCP協議。網絡層:通過路由選擇算法為分組通過通信子網選擇最適當的途徑,以及實現擁塞控制、網絡互聯等功能。數據傳輸單元是分組。IP地址,路由器,IP協議。數據鏈路層:在物理層提供的服務基礎上,數據鏈路層在通信的實體間建立數據鏈路連接,傳輸一幀為單位的數據包(,并采用差錯控制與流量控制方法,使有差錯的物理線路變成無差錯的數據鏈路。)物理層:傳輸比特流。傳輸單元是比特。調制解調器。56請你具體地解釋一下IP協議的定義,在哪個層上面?重要有什么作用?TCP與UDP呢?網絡層。57.請問互換機和路由器各自的實現原理是什么?分別在哪個層次上面實現的?互換機:數據鏈路層。路由器:網絡層。58.全局變量和局部變量有什么區別?是怎么實現的?操作系統和編譯器是怎么知道的?59.8086是多少位的系統?在數據總線上是怎么實現的??8086微解決器共有4個16位的段寄存器,在尋址內存單元時,用它們直接或間接地存放段地址。代碼段寄存器CS:存放當前執行的程序的段地址。數據段寄存器DS:存放當前執行的程序所用操作數的段地址。堆棧段寄存器SS:存放當前執行的程序所用堆棧的段地址。附加段寄存器ES:存放當前執行程序中一個輔助數據段的段地址。由cs:ip構成指令地址,ss:sp構成堆棧的棧頂地址指針。DS和ES用作數據段和附加段的段地址(段起始地址或段值)8086/8088微解決器的存儲器管理
1.地址線(碼)與尋址范圍:N條地址線尋址范圍=2N
2.8086有20地址線尋址范圍為1MB由00000H~FFFFFH
3.8086微解決器是一個16位結構,用戶可用的寄存器均為16位:尋址64KB
4.8086/8088采用分段的方法對存儲器進行管理。具體做法是:把1MB的存儲器空間提成若干段,每段容量為64KB,每段存儲器的起始地址必須是一個能被16整除的地址碼,即在20位的二進制地址碼中最低4位必須是“0”。每個段首地址的高16位二進制代碼就是該段的段號(稱段基地址)或簡稱段地址,段號保存在段寄存器中。我們可對段寄存器設立不同的值來使微解決器的存儲器訪問指向不同的段。
5.段內的某個存儲單元相對于該段段首地址的差值,稱為段內偏移地址(也叫偏移量)用16位二進制代碼表達。
6.物理地址是由8086/8088芯片地址引線送出的20位地址碼,它用來參與存儲器的地址譯碼,最終讀/寫所訪問的一個特定的存儲單元。
7.邏輯地址由某段的段地址和段內偏移地址(也叫偏移量)兩部分所組成。寫成:段地址:偏移地址(例如,1234H:0088H)。
8.在硬件上起作用的是物理地址,物理地址=段基地址×10H十偏移地址聯想筆試題
1.設計函數intatoi(char*s)。int
atoi(const
char
*s)
{
if(!str)
returnINF;?
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.什么是中斷?中斷發生時CPU做什么工作?2.CPU在上電后,進入操作系統的main()之前必須做什么工作?3.簡述ISOOSI的物理層Layer1,鏈路層Layer2,網絡層Layer3的任務。4.有線電話和無線電話有何區別?無線電話特別需要注意的是什么?5軟件開發五個重要step是什么?6.你在開發軟件的時候,這5個step分別占用的時間比例是多少?7.makefile文獻的作用是什么?8.UNIX顯示文獻夾中,文獻名的命令是什么?能使文獻內容顯示在屏幕的命令是什么?9.(選做)手機用戶在從一個基站漫游到另一個基站的過程中,都會發生什么??簡答題(每題10分)1.簡述普通電話與IP電話的區別。2.簡述隨路信令與公路信令的主線區別。3.說明掩碼的重要作用。4.ss7協議中,有三大要素決定其具體定位,哪三大要素?5.描述ss7的基本通話過程。6.簡述通信網的組成結構。7.面向連接與面向非連接各有何利弊?8.寫出愛爾蘭的基本計算公式。9.數據網重要有哪些設備?10.中國一號協議是如何在被叫號碼中插入主叫號碼的?
東信筆試:30分鐘。1.壓控振蕩器的英文縮寫。2.動態隨機存儲器的英文縮寫。3.選擇電阻時要考慮什么?4.單片機上電后沒有運轉,一方面要檢查什么?5.計算機的基本組成部分及其各自的作用。6.如何用D觸發器、與或非門組成二分頻電路?64.static有什么用途?(請至少說明兩種)答、1.限制變量的作用域(文獻級的)。2.設立變量的存儲域(全局數據區)。66.描述實時系統的基本特性?答:在特定期間內完畢特定的任務,實時性與可靠性。67.全局變量和局部變量在內存中是否有區別?假如有,是什么區別?答、全局變量儲存在靜態數據區,局部變量在堆棧中。68.什么是平衡二叉樹?答、左右子樹都是平衡二叉樹且左右子樹的深度差值的絕對值不大于1。69.堆棧溢出一般是由什么因素導致的?答:1.沒有回收垃圾資源 2.層次太深的遞歸調用?70.什么函數不能聲明為虛函數?答:constructor Deconstructor可以聲明為虛函數。 系統為一個空類創建的成員函數有那些。默認構造函數析構函數拷貝構造函數賦值運算符(operator=)取址運算符(operator&)(一對,一個非const的,一個const的)當然,所有這些只有當被需要才會產生。比如你定義了一個類,但歷來定義過該類的對象,也沒使用過該類型的函數參數,那么基本啥也不會產生。在比如你歷來沒有進行過該類型對象之間的賦值,那么operator=不會被產生。71.冒泡排序算法的時間復雜度是什么?答:O(n^2)72.寫出floatx與“零值”比較的if語句。答、if(x>0.000001&&x<-0.000001)73.Internet采用哪種網絡協議?該協議的重要層次結構?答:tcp/ip應用層/傳輸層/網絡層/數據鏈路層/物理層74.Internet物理地址和IP地址轉換采用什么協議?答、ARP(AddressResolutionProtocol)(地址解析協議)75.IP地址的編碼分為哪倆部分?答、IP地址由兩部分組成,網絡號和主機號。但是是要和“子網掩碼”按位與之后才干區分哪些是網絡位哪些是主機位。76.用戶輸入M,N值,從1至N開始順序循環數數,每數到M輸出該數值,直至所有輸出。寫出C程序。答:循環鏈表,用取余操作做77.不能做switch()的參數類型是:答:switch的參數不能為實型。78.局部變量能否和全局變量重名?答:能,局部會屏蔽全局。要用全局變量,需要使用"::"局部變量可以與全局變量同名,在函數內引用這個變量時,會用到同名的局部變量,而不會用到全局變量。對于有些編譯器而言,在同一個函數內可以定義多個同名的局部變量,比如在兩個循環體內都定義一個同名的局部變量,而那個局部變量的作用域就在那個循環體內79.如何引用一個已經定義過的全局變量?答:可以用引用頭文獻的方式,也可以用extern關鍵字,假如用引用頭文獻方式來引用某個在頭文獻中聲明的全局變理,假定你將那個變量寫錯了,那么在編譯期間會報錯,假如你用extern方式引用時,假定你犯了同樣的錯誤,那么在編譯期間不會報錯,而在連接期間報錯80.全局變量可不可以定義在可被多個.C文獻包含的頭文獻中?為什么?答:可以,在不同的C文獻中以static形式來聲明同名全局變量。可以在不同的C文獻中聲明同名的全局變量,前提是其中只能有一個C文獻中對此變量賦初值,此時連接不會犯錯81.語句for(;1;)有什么問題?它是什么意思?答:和while(1)相同。82.do……while和while……do有什么區別?答:前一個循環一遍再判斷,后一個判斷以后再循環83.請寫出下列代碼的輸出內容答: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.statac全局變量、局部變量、函數與普通全局變量、局部變量、函數:static全局變量與普通的全局變量有什么區別?static局部變量和普通局部變量有什么區別?static函數與普通函數有什么區別?答、全局變量(外部變量)的說明之前再冠以static就構成了靜態的全局變量。全局變量自身就是靜態存儲方式,靜態全局變量當然也是靜態存儲方式。這兩者在存儲方式上并無不同。這兩者的區別雖在于非靜態全局變量的作用域是整個源程序,當一個源程序由多個源文獻組成時,非靜態的全局變量在各個源文獻中都是有效的。而靜態全局變量則限制了其作用域,即只在定義該變量的源文獻內有效,在同一源程序的其它源文獻中不能使用它。由于靜態全局變量的作用域局限于一個源文獻內,只能為該源文獻內的函數公用,因此可以避免在其它源文獻中引起錯誤。從以上分析可以看出,把局部變量改變為靜態變量后是改變了它的存儲方式即改變了它的生存期。把全局變量改變為靜態變量后是改變了它的作用域,限制了它的使用范圍。static函數與普通函數作用域不同。僅在本文獻。只在當前源文獻中使用的函數應當說明為內部函數(static),內部函數應當在當前源文獻中說明和定義。對于可在當前源文獻以外使用的函數,應當在一個頭文獻中說明,要使用這些函數的源文獻要包含這個頭文獻static全局變量與普通的全局變量有什么區別:static全局變量只初使化一次,防止在其他文獻單元中被引用;static局部變量和普通局部變量有什么區別:static局部變量只被初始化一次,下一次依據上一次結果值;static函數與普通函數有什么區別:static函數在內存中只有一份,普通函數在每個被調用中維持一份拷貝程序的局部變量存在于(堆棧)中,全局變量存在于(靜態區)中,動態申請數據存在于(堆)中。85.設有以下說明和定義:typedefunion{longi;intk[5];charc;}DATE;structdata{intcat;DATEcow;doubledog;}too;DATEmax;則語句printf("%d",sizeof(structdate)+sizeof(max));的執行結果是?答、結果是:___52____。DATE是一個union,變量公用空間.里面最大的變量類型是int[5],占用20個字節.所以它的大小是20。data是一個struct,每個變量分開占用空間.依次為int4+DATE20+double8=32.所以結果是20+32=52.當然...在某些16位編輯器下,int也許是2字節,那么結果是int2+DATE10+double8=2086.-1,2,7,28,,126請問28和126中間那個數是什么?為什么?答、應當是4^3-1=63規律是n^3-1(當n為偶數0,2,4)n^3+1(當n為奇數1,3,5)87.用兩個棧實現一個隊列的功能?規定給出算法和思緒!答、設2個棧為A,B,一開始均為空.入隊:將新元素push入棧A;出隊:(1)判斷棧B是否為空;(2)假如不為空,則將棧A中所有元素依次pop出并push到棧B;(3)將棧B的棧頂元素pop出;這樣實現的隊列入隊和出隊的平攤復雜度都還是O(1),比上面的幾種方法要好。88.在c語言庫函數中將一個字符轉換成整型的函數是atool()嗎,這個函數的原型是什么?答:函數名:atol功能:把字符串轉換成長整型數用法:longatol(constchar*nptr);程序例:#include#includeintmain(void){longl;char*str="98765432";l=atol(lstr);printf("string=%sinteger=%ld\n",str,l);return(0);}89.對于一個頻繁使用的短小函數,在C語言中應用什么實現,在C++中應用什么實現?答、c用宏定義,c++用inline90.用預解決指令#define聲明一個常數,用以表白1年中有多少秒(忽略閏年問題)#defineSECONDS_PER_YEAR(60*60*24*365)UL我在這想看到幾件事情:1).#define語法的基本知識(例如:不能以分號結束,括號的使用,等等)2).懂得預解決器將為你計算常數表達式的值,因此,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清楚而沒有代價的。3).意識到這個表達式將使一個16位機的整型數溢出-因此要用到長整型符號L,告訴編譯器這個常數是的長整型數。4).假如你在你的表達式中用到UL(表達無符號長整型),那么你有了一個好的起點。記住,第一印象很重要。91.寫一個“標準”宏MIN,這個宏輸入兩個參數并返回較小的一個。#defineMIN(A,B)((A)<=(B)(A):(B))這個測試是為下面的目的而設的:1).標記#define在宏中應用的基本知識。這是很重要的,由于直到嵌入(inline)操作符變為標準C的一部分,宏是方便產生嵌入代碼的唯一方法,對于嵌入式系統來說,為了能達成規定的性能,嵌入代碼經常是必須的方法。2).三重條件操作符的知識。這個操作符存在C語言中的因素是它使得編譯器能產生比if-then-else更優化的代碼,了解這個用法是很重要的。3).懂得在宏中小心地把參數用括號括起來4).我也用這個問題開始討論宏的副作用,例如:當你寫下面的代碼時會發生什么事?least=MIN(*p++,b);92.預解決器標記#error的目的是什么?假如你不知道答案,請看參考文獻1。這問題對區分一個正常的伙計和一個書呆子是很有用的。只有書呆子才會讀C語言課本的附錄去找出象這種問題的答案。當然假如你不是在找一個書呆子,那么應試者最佳希望自己不要知道答案。死循環(Infiniteloops)93.嵌入式系統中經常要用到無限循環,你怎么樣用C編寫死循環呢?這個問題用幾個解決方案。我首選的方案是:while(1){}一些程序員更喜歡如下方案:for(;1;){}這個實現方式讓我為難,由于這個語法沒有確切表達成底怎么回事。假如一個應試者給出這個作為方案,我將用這個作為一個機會去探究他們這樣做的基本原理。假如他們的基本答案是:“我被教著這樣做,但從沒有想到過為什么。”這會給我留下一個壞印象。第三個方案是用gotoLoop:...gotoLoop;應試者如給出上面的方案,這說明或者他是一個匯編語言程序員(這也許是好事)或者他是一個想進入新領域的BASIC/FORTRAN程序員。數據聲明(Datadeclarations)94.用變量a給出下面的定義a)一個整型數(Aninteger)b)一個指向整型數的指針(Apointertoaninteger)c)一個指向指針的的指針,它指向的指針是指向一個整型數(Apointertoapointertoaninteger)d)一個有10個整型數的數組(Anarrayof10integers)e)一個有10個指針的數組,該指針是指向一個整型數的(Anarrayof10pointerstointegers)f)一個指向有10個整型數數組的指針(Apointertoanarrayof10integers)g)一個指向函數的指針,該函數有一個整型參數并返回一個整型數(Apointertoafunctionthattakesanintegerasanargumentandreturnsaninteger)h)一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數并返回一個整型數(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.關鍵字static的作用是什么?在C語言中,關鍵字static有三個明顯的作用:1).在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。2).在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。3).在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地范圍內使用。Const96.關鍵字const是什么含意?我只要一聽到被面試者說:“const意味著常數”,我就知道我正在和一個業余者打交道。去年DanSaks已經在他的文章里完全概括了const的所有用法,因此ESP(譯者:EmbeddedSystemsProgramming)的每一位讀者應當非常熟悉const能做什么和不能做什么.假如你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。盡管這個答案不是完全的答案,但我接受它作為一個對的的答案。(假如你想知道更具體的答案,仔細讀一下Saks的文章吧。)假如應試者能對的回答這個問題,我將問他一個附加的問題:下面的聲明都是什么意思?constinta;intconsta;constint*a;int*consta;intconst*aconst;前兩個的作用是同樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指針(也就是,整型數是不可修改的,但指針可以)。第四個意思a是一個指向整型數的常指針(也就是說,指針指向的整型數是可以修改的,但指針是不可修改的)。最后一個意味著a是一個指向常整型數的常指針(也就是說,指針指向的整型數是不可修改的,同時指針也是不可修改的)。假如應試者能對的回答這些問題,那么他就給我留下了一個好印象。順帶提一句,也許你也許會問,即使不用關鍵字const,也還是能很容易寫出功能對的的程序,那么我為什么還要如此看重關鍵字const呢?我也如下的幾下理由:1).關鍵字const的作用是為給讀你代碼的人傳達非常有用的信息,事實上,聲明一個參數為常量是為了告訴了用戶這個參數的應用目的。假如你曾花很多時間清理其它人留下的垃圾,你就會不久學會感謝這點多余的信息。(當然,懂得用const的程序員很少會留下的垃圾讓別人來清理的。)2).通過給優化器一些附加的信息,使用關鍵字const也許能產生更緊湊的代碼。3).合理地使用關鍵字const可以使編譯器很自然地保護那些不希望被改變的參數,防止其被無意的代碼修改。簡而言之,這樣可以減少bug的出現。Volatile97.關鍵字volatile有什么含意并給出三個不同的例子。一個定義為volatile的變量是說這變量也許會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。下面是volatile變量的幾個例子:1).并行設備的硬件寄存器(如:狀態寄存器)2).一個中斷服務子程序中會訪問到的非自動變量(Non-automaticvariables)3).多線程應用中被幾個任務共享的變量回答不出這個問題的人是不會被雇傭的。我認為這是區分C程序員和嵌入式系統程序員的最基本的問題。嵌入式系統程序員經常同硬件、中斷、RTOS等等打交道,所用這些都規定volatile變量。不懂得volatile內容將會帶來劫難。假設被面試者對的地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看一下這家伙是不是直正懂得volatile完全的重要性。1).一個參數既可以是const還可以是volatile嗎?解釋為什么。2).一個指針可以是volatile嗎?解釋為什么。3).下面的函數有什么錯誤:intsquare(volatileint*ptr){return*ptr**ptr;}下面是答案:1).是的。一個例子是只讀的狀態寄存器。它是volatile由于它也許被意想不到地改變。它是const由于程序不應當試圖去修改它。2).是的。盡管這并不很常見。一個例子是當一個中服務子程序修該一個指向一個buffer的指針時。3).這段代碼的有個惡作劇。這段代碼的目的是用來返指針*ptr指向值的平方,但是,由于*ptr指向一個volatile型參數,編譯器將產生類似下面的代碼:intsquare(volatileint*ptr){inta,b;a=*ptr;b=*ptr;returna*b;}由于*ptr的值也許被意想不到地該變,因此a和b也許是不同的。結果,這段代碼也許返不是你所盼望的平方值!對的的代碼如下:longsquare(volatileint*ptr){inta;a=*ptr;returna*a;}位操作(Bitmanipulation)98.下面的代碼輸出是什么,為什么?voidfoo(void){unsignedinta=6;intb=-20;(a+b>6)puts(">6"):puts("<=6");}這個問題測試你是否懂得C語言中的整數自動轉換原則,我發現有些開發者懂得很少這些東西。不管如何,這無符號整型問題的答案是輸出是“>6”。因素是當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換為無符號類型。因此-20變成了一個非常大的正整數,所以該表達式計算出的結果大于6。這一點對于應當頻繁用到無符號數據類型的嵌入式系統來說是豐常重要的。假如你答錯了這個問題,你也就到了得不到這份工作的邊沿。99.C語言批準一些令人震驚的結構,下面的結構是合法的嗎,假如是它做些什么?inta=5,b=7,c;c=a+++b;這個問題將做為這個測驗的一個快樂的結尾。不管你相不相信,上面的例子是完全合乎語法的。問題是編譯器如何解決它?水平不高的編譯作者事實上會爭論這個問題,根據最解決原則,編譯器應當能解決盡也許所有合法的用法。因此,上面的代碼被解決成:c=a+++b;因此,這段代碼持行后a=6,b=7,c=12。假如你知道答案,或猜出對的答案,做得好。假如你不知道答案,我也不把這個當作問題。我發現這個問題的最大好處是:這是一個關于代碼編寫風格,代碼的可讀性,代碼的可修改性的好的話題,100.線形表a、b為兩個有序升序的線形表,編寫一程序,使兩個有序線形表合并成一個有序升序線形表h;答案在請化大學嚴銳敏《數據結構第二版》第二章例題,數據結構當中,這個叫做:兩路歸并排序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!=NULL)ra->next=pa;if(qa->next!=NULL)ra->next==qa;returnR;}101.用遞歸算法判斷數組a[N]是否為一個遞增數組。遞歸的方法,記錄當前最大的,并且判斷當前的是否比這個還大,大則繼續,否則返回false結束:boolfun(inta[],intn){if(n==1
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 涂料店鋪布局優化考核試卷
- 《萬里長征》新民主主義革命的興起課件
- 文案-北京明天第一城商業策劃案
- DB11 T 384.13-2009 圖像信息管理系統技術規范 第13部分 圖像信息存儲系統
- 小升初-盈虧問題
- 財務管理需要學的知識體系
- 人工工資承包合同二零二五年
- 二零二五版車輛租賃合同保證金擔保
- 吉粳557品種簡介
- 基金份額代持協議二零二五年
- crystalball模擬基礎教程課件
- 物資倉庫防洪防汛應急預案
- .三坐標測量員技能考核考試題答案
- 大學語文課程建設與改革實施方案
- 【上海市靜安區寶山路街道社區養老問題調查報告】
- 公文筐測驗(案例題解示范)
- 大學森林生態教案
- 蛙泳教學教案
- 醫學英語詞匯學(山東聯盟)智慧樹知到答案章節測試2023年山東第一醫科大學
- 口腔一般檢查方法口腔一般檢查方法
- 冠狀動脈粥樣硬化性心臟病 (心內科)
評論
0/150
提交評論