版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1.new、delete、malloc、free關系delete會調用對象的析構函數,和new相應free只會釋放內存,new調用構造函數。malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用于申請動態(tài)內存和釋放內存。對于非內部數據類型的對象而言,光用maloc/free無法滿足動態(tài)對象的規(guī)定。對象在創(chuàng)建的同時要自動執(zhí)行構造函數,對象在消亡之前要自動執(zhí)行析構函數。由于malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不可以把執(zhí)行構造函數和析構函數的任務強加于malloc/free。因此C++語言需要一個能完畢動態(tài)內存分派和初始化工作的運算符new,以及一個能完畢清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。2.delete與delete[]區(qū)別delete只會調用一次析構函數,而delete[]會調用每一個成員的析構函數。在MoreEffectiveC++中有更為具體的解釋:“當delete操作符用于數組時,它為每個數組元素調用析構函數,然后調用operatordelete來釋放內存?!眃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-處報錯。這就說明:對于內建簡樸數據類型,delete和delete[]功能是相同的。對于自定義的復雜數據類型,delete和delete[]不能互用。delete[]刪除一個數組,delete刪除一個指針簡樸來說,用new分派的內存用delete刪除用new[]分派的內存用delete[]刪除delete[]會調用數組元素的析構函數。內部數據類型沒有析構函數,所以問題不大。假如你在用delete時沒用括號,delete就會認為指向的是單個對象,否則,它就會認為指向的是一個數組。3.C和C++的共同點?不同之處?C是面向過程的語言,C++是HYPERLINK""\t"_blank"面向對象,但是不全是。HYPERLINK""\t"_blank"JAVA是純HYPERLINK""\t"_blank"面向對象在語言層面上,C++和JAVA都基本同樣,只是JAVA語言去掉了指針,多繼承等容易犯錯的東東.現在的JAVA不單純的是指語言,它是一個開發(fā)平臺的通稱,Java的通用性好,可以跨平臺直接移植,只要有安裝Java虛擬機(JVM)就可以了。開發(fā)的效率高。生成的機器碼效率沒有匯編和C的高。4.繼承的優(yōu)缺陷。類繼承是在編譯時刻靜態(tài)定義的,且可直接使用,類繼承可以較方便地改變父類的實現。但是類繼承也有一些局限性之處。一方面,由于繼承在編譯時刻就定義了,所以無法在運營時刻改變從父類繼承的實現。更糟的是,父類通常至少定義了子類的部分行為,父類的任何改變都也許影響子類的行為。假如繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他更適合的類替換。這種依賴關系限制了靈活性并最終限制了復用性。(待補充)5.C++有哪些性質(面向對象特點)封裝,繼承和多態(tài)。在面向對象程序設計語言中,封裝是運用可重用成分構造軟件系統(tǒng)的特性,它不僅支持系統(tǒng)的可重用性,并且尚有助于提高系統(tǒng)的可擴充性;消息傳遞可以實現發(fā)送一個通用的消息而調用不同的方法;封裝是實現信息隱蔽的一種技術,其目的是使類的定義和實現分離。6.子類析構時要調用父類的析構函數嗎?析構函數調用的順序是先派生類的析構后基類的析構,也就是說在基類的的析構調用的時候,派生類的信息已經所有銷毀了定義一個對象時先調用基類的構造函數、然后調用派生類的構造函數;析構的時候恰好相反:先調用派生類的析構函數、然后調用基類的析構函數;JAVA無析構函數深拷貝和淺拷貝7.多態(tài),虛函數,純虛函數多態(tài):是對于不同對象接受相同消息時產生不同的動作。C++的多態(tài)性具體體現在運營和編譯兩個方面:在程序運營時的多態(tài)性通過繼承和虛函數來體現;在程序編譯時多態(tài)性體現在函數和運算符的重載上虛函數:在基類中冠以關鍵字virtual的成員函數。它提供了一種接口界面。允許在派生類中對基類的虛函數重新定義。純虛函數的作用:在基類中為其派生類保存一個函數的名字,以便派生類根據需要對它進行定義。作為接口而存在純虛函數不具有函數的功能,一般不能直接被調用。從基類繼承來的純虛函數,在派生類中仍是虛函數。假如一個類中至少有一個純虛函數,那么這個類被稱為抽象類(abstractclass)。抽象類中不僅涉及純虛函數,也可涉及虛函數。l抽象類必須用作派生其他類的基類,而不能用于直接創(chuàng)建對象實例。但仍可使用指向抽象類的指針支持運營時多態(tài)性。8.求下面函數的返回值(微軟)intfunc(x)
{?intcountx=0;?while(x)
{?countx++;
x=x&(x-1);
}?returncountx;?}假定x=9999。答案:8思緒:將x轉化為2進制,看具有的1的個數。9.什么是“引用”?申明和使用“引用”要注意哪些問題?答:引用就是某個目的變量的“別名”(alias),相應用的操作與對變量直接操作效果完全相同。申明一個引用的時候,牢記要對其進行初始化。引用聲明完畢后,相稱于目的變量名有兩個名稱,即該目的原名稱和引用名,不能再把該引用名作為其他變量名的別名。聲明一個引用,不是新定義了一個變量,它只表達該引用名是目的變量名的一個別名,它自身不是一種數據類型,因此引用自身不占存儲單元,系統(tǒng)也不給引用分派存儲單元。不能建立數組的引用。10.將“引用”作為函數參數有哪些特點?(1)傳遞引用給函數與傳遞指針的效果是同樣的。這時,被調函數的形參就成為本來主調函數中的實參變量或對象的一個別名來使用,所以在被調函數中對形參變量的操作就是對其相應的目的對象(在主調函數中)的操作。(2)使用引用傳遞函數的參數,在內存中并沒有產生實參的副本,它是直接對實參操作;而使用一般變量傳遞函數的參數,當發(fā)生函數調用時,需要給形參分派存儲單元,形參變量是實參變量的副本;假如傳遞的是對象,還將調用拷貝構造函數。因此,當參數傳遞的數據較大時,用引用比用一般變量傳遞參數的效率和所占空間都好。(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.將“引用”作為函數返回值類型的格式、好處和需要遵守的規(guī)則?格式:類型標記符&函數名(形參列表及類型說明){//函數體}好處:在內存中不產生被返回值的副本;(注意:正是由于這點因素,所以返回一個局部變量的引用是不可取的。由于隨著該局部變量生存期的結束,相應的引用也會失效,產生runtimeerror!注意事項:(1)不能返回局部變量的引用。這條可以參照EffectiveC++[1]的Item31。重要因素是局部變量會在函數返回后被銷毀,因此被返回的引用就成為了"無所指"的引用,程序會進入未知狀態(tài)。(2)不能返回函數內部new分派的內存的引用。這條可以參照EffectiveC++[1]的Item31。雖然不存在局部變量的被動銷毀問題,可對于這種情況(返回函數內部new分派內存的引用),又面臨其它尷尬局面。例如,被函數返回的引用只是作為一個臨時變量出現,而沒有被賦予一個實際的變量,那么這個引用所指向的空間(由new分派)就無法釋放,導致memoryleak。(3)可以返回類成員的引用,但最佳是const。這條原則可以參照EffectiveC++[1]的Item30。重要因素是當對象的屬性是與某種業(yè)務規(guī)則(businessrule)相關聯的時候,其賦值經常與某些其它屬性或者對象的狀態(tài)有關,因此有必要將賦值操作封裝在一個業(yè)務規(guī)則當中。假如其它對象可以獲得該屬性的非常量引用(或指針),那么對該屬性的單純賦值就會破壞業(yè)務規(guī)則的完整性。(4)流操作符重載返回值申明為“引用”的作用:流操作符<<和>>,這兩個操作符經常希望被連續(xù)使用,例如:cout<<"hello"<<endl;因此這兩個操作符的返回值應當是一個仍然支持這兩個操作符的流引用??蛇x的其它方案涉及:返回一個流對象和返回一個流對象指針。但是對于返回一個流對象,程序必須重新(拷貝)構造一個新的流對象,也就是說,連續(xù)的兩個<<操作符事實上是針對不同對象的!這無法讓人接受。對于返回一個流指針則不能連續(xù)使用<<操作符。因此,返回一個流對象引用是惟一選擇。這個唯一選擇很關鍵,它說明了引用的重要性以及無可替代性,也許這就是C++語言中引入引用這個概念的因素吧。賦值操作符=。這個操作符象流操作符同樣,是可以連續(xù)使用的,例如:x=j=10;或者(x=10)=100;賦值操作符的返回值必須是一個左值,以便可以被繼續(xù)賦值。因此引用成了這個操作符的惟一返回值選擇。例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分派的對象的引用、返回一個靜態(tài)對象引用。根據前面提到的引用作為返回值的三個規(guī)則,第2、3兩個方案都被否決了。靜態(tài)對象的引用又由于((a+b)==(c+d))會永遠為true而導致錯誤。所以可選的只剩下返回一個對象了。13.“引用”與多態(tài)的關系?引用是除指針外另一個可以產生多態(tài)效果的手段。這意味著,一個基類的引用可以指向它的派生類實例。例4ClassA;ClassB:ClassA{...};Bb;A&ref=b;14.“引用”與指針的區(qū)別是什么?指針通過某個指針變量指向一個對象后,對它所指向的變量間接操作。程序中使用指針,程序的可讀性差;而引用自身就是目的變量的別名,對引用的操作就是對目的變量的操作。此外,就是上面提到的對函數傳ref和pointer的區(qū)別。15.什么時候需要“引用”?流操作符<<和>>、賦值操作符=的返回值、拷貝構造函數的參數、賦值操作符=的參數、其它情況都推薦使用引用。以上2-8參考:16.結構與聯合有和區(qū)別??(1).結構和聯合都是由多個不同的數據類型成員組成,但在任何同一時刻,聯合中只存放了一個被選中的成員(所有成員共用一塊地址空間),而結構的所有成員都存在(不同成員的存放地址不同)。
(2).對于聯合的不同成員賦值,將會對其它成員重寫,本來成員的值就不存在了,而對于結構的不同成員賦值是互不影響的。17.面關于“聯合”的題目的輸出?a)#include<stdio.h>?union?{
inti;
charx[2];?}a;
voidmain()?{
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)的區(qū)別?涉及到UML中的一些概念:關聯是表達兩個類的一般性聯系,比如“學生”和“老師”就是一種關聯關系;聚合表達has-a的關系,是一種相對松散的關系,聚合類不需要對被聚合類負責,如下圖所示,用空的菱形表達聚合關系:從實現的角度講,聚合可以表達為:classA{...}classB{A*a;.....}而組合表達contains-a的關系,關聯性強于聚合:組合類與被組合類有相同的生命周期,組合類要對被組合類負責,采用實心的菱形表達組合關系:實現的形式是:classA{...}classB{Aa;...}19.面向對象的三個基本特性,并簡樸敘述之?1.封裝:將客觀事物抽象成類,每個類對自身的數據和方法實行protection(privat(yī)e,protected,public)2.繼承:廣義的繼承有三種實現形式:實現繼承(指使用基類的屬性和方法而無需額外編碼的能力)、可視繼承(子窗體使用父窗體的外觀和實現代碼)、接口繼承(僅使用屬性和方法,實現滯后到子類實現)。前兩種(類繼承)和后一種(對象組合=>接口繼承以及純虛函數)構成了功能復用的兩種方式。3.多態(tài):是將父對象設立成為和一個或更多的他的子對象相等的技術,賦值之后,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡樸的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針。20.重載(overload)和重寫(overried,有的書也叫做“覆蓋”)的區(qū)別???嫉念}目。從定義上來說:重載:是指允許存在多個同名函數,而這些函數的參數表不同(或許參數個數不同,或許參數類型不同,或許兩者都不同)。重寫:是指子類重新定義父類虛函數的方法。從實現原理上來說:重載:編譯器根據函數不同的參數表,對同名函數的名稱做修飾,然后這些同名函數就成了不同的函數(至少對于編譯器來說是這樣的)。如,有兩個同名函數:functionfunc(p:integer):integer;和functionfunc(p:string):integer;。那么編譯器做過修飾后的函數名稱也許是這樣的:int_func、str_func。對于這兩個函數的調用,在編譯器間就已經擬定了,是靜態(tài)的。也就是說,它們的地址在編譯期就綁定了(早綁定),因此,重載和多態(tài)無關!重寫:和多態(tài)真正相關。當子類重新定義了父類的虛函數后,父類指針根據賦給它的不同的子類指針,動態(tài)的調用屬于子類的該函數,這樣的函數調用在編譯期間是無法擬定的(調用的子類的虛函數的地址無法給出)。因此,這樣的函數地址是在運營期綁定的(晚綁定)。21.多態(tài)的作用?重要是兩個:1.隱藏實現細節(jié),使得代碼可以模塊化;擴展代碼模塊,實現代碼重用;2.接口重用:為了類在繼承和派生的時候,保證使用家族中任一類的實例的某一屬性時的對的調用。22.Ado與Ado.net的相同與不同?除了“可以讓應用程序解決存儲于DBMS中的數據“這一基本相似點外,兩者沒有太多共同之處。但是Ado使用OLEDB接口并基于微軟的COM技術,而ADO.NET擁有自己的ADO.NET接口并且基于微軟的.NET體系架構。眾所周知.NET體系不同于COM體系,ADO.NET接口也就完全不同于ADO和OLEDB接口,這也就是說ADO.NET和ADO是兩種數據訪問方式。ADO.net提供對XML的支持。23.Newdelete與mallocfree的聯系與區(qū)別?答案:都是在堆(heap)上進行動態(tài)的內存操作。用malloc函數需要指定內存分派的字節(jié)數并且不能初始化對象,new會自動調用對象的構造函數。delete會調用對象的destructor,而free不會調用對象的destructor.24.#defineDOUBLE(x)x+x,i=5*DOUBLE(5);i是多少?答案:i為30。25.有哪幾種情況只能用intializationlist而不能用assignment?1.當類中具有const、reference成員變量,對象成員;基類的構造函數都需要初始化。2.當基類有帶參構造,子類就應當聲明一個將參數傳遞給基類構造函數的途徑。3.當基類派生子類對象時,就要對基類數據成員等初始化。(1)#include<iostream>
usingnamespacestd;classA{?private:?constinta;//const成員
constintb;//const成員
public:
A(inti,intj):a(i),b(j){}//必須在這里初始化?};intmain(){
Aa(1,2);
return0;?}(2)#include<iostream>
usingnamespacestd;classA{?private:?intx1;?public:?A(inti){//只有一個帶參的構造函數
x1=i;?}?};
classB:publicA{
private:
intx2;?public:?B(inti):A(i+10){//必須在這里初始化?x2=i;?}?};intmain(){
Bb(2);
return0;
}26.C++是不是類型安全的?答案:不是。兩個不同類型的指針之間可以強制轉換(用reinterpretcast)。C#是類型安全的。27.main函數執(zhí)行以前,還會執(zhí)行什么代碼?答案:全局對象的構造函數會在main函數之前執(zhí)行。一、main結束不代表整個進程結束?(1)全局對象的構造函數會在main函數之前執(zhí)行,
全局對象的析構函數會在main函數之后執(zhí)行;?用atexit注冊的函數也會在main之后執(zhí)行。?(2)一些全局變量、對象和靜態(tài)變量、對象的空間分派和賦初值就是在執(zhí)行main函數之前,而main函數執(zhí)行完后,還要去執(zhí)行一些諸如釋放空間、釋放資源使用權等操作
(3)進程啟動后,要執(zhí)行一些初始化代碼(如設立環(huán)境變量等),然后跳轉到main執(zhí)行。全局對象的構造也在main之前。
二、main()之后執(zhí)行的代碼,用at(yī)exit注冊的函數也會在main之后執(zhí)行28.描述內存分派方式以及它們的區(qū)別?1)從靜態(tài)存儲區(qū)域分派。內存在程序編譯的時候就已經分派好,這塊內存在程序的整個運營期間都存在。例如全局變量,static變量。?2)在棧上創(chuàng)建。在執(zhí)行函數時,函數內局部變量的存儲單元都可以在棧上創(chuàng)建,函數執(zhí)行結束時這些存儲單元自動被釋放。棧內存分派運算內置于解決器的指令集。
3)從堆上分派,亦稱動態(tài)內存分派。程序在運營的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態(tài)內存的生存期由程序員決定,使用非常靈活,但問題也最多。29.struct和class的區(qū)別答案:struct的成員默認是公有的,而類的成員默認是私有的。struct和class在其他方面是功能相稱的。從感情上講,大多數的開發(fā)者感到類和結構有很大的差別。感覺上結構僅僅象一堆缺少封裝和功能的開放的內存位,而類就象活的并且可靠的社會成員,它有智能服務,有牢固的封裝屏障和一個良好定義的接口。既然大多數人都這么認為,那么只有在你的類有很少的方法并且有公有數據(這種事情在良好設計的系統(tǒng)中是存在的!)時,你也許應當使用struct關鍵字,否則,你應當使用class關鍵字。30.當一個類A中沒有任何成員變量與成員函數,這時sizeof(A)的值是多少?答案:一個空類對象的大小是1byte。這是被編譯器安插進去的一個字節(jié),這樣就使得這個空類的兩個實例得以在內存中配置獨一無二的地址也就是說這個char是用來標記類的不同對象的。31.在8086匯編下,邏輯地址和物理地址是如何轉換的?(Intel)答案:通用寄存器給出的地址,是段內偏移地址,相應段寄存器地址*10H+通用寄存器內地址,就得到了真正要訪問的地址。32.比較C++中的4種類型轉換方式?類型轉換有c風格的,當然尚有c++風格的。c風格的轉換的格式很簡樸(TYPE)EXPRESSION,但是c風格的類型轉換有不少的缺陷,有的時候用c風格的轉換是不合適的,由于它可以在任意類型之間轉換,比如你可以把一個指向const對象的指針轉換成指向非const對象的指針,把一個指向基類對象的指針轉換成指向一個派生類對象的指針,這兩種轉換之間的差別是巨大的,但是傳統(tǒng)的c語言風格的類型轉換沒有區(qū)分這些。尚有一個缺陷就是,c風格的轉換不容易查找,他由一個括號加上一個標記符組成,而這樣的東西在c++程序里一大堆。所以c++為了克服這些缺陷,引進了4新的類型轉換操作符,他們是1.static_cast2.const_cast3.dynamic_cast4.reinterpret_cast.1.static_cast最常用的類型轉換符,在正常狀況下的類型轉換,如把int轉換為float,如:inti;float(yī)f;f=(float(yī))i;或者f=static_cast<float>(i);2.const_cast用于取出const屬性,把const類型的指針變?yōu)榉莄onst類型的指針,如:constint*fun(intx,inty){}int*ptr=const_cast<int*>(fun(2.3))3.dynamic_cast該操作符用于運營時檢查該轉換是否類型安全,但只在多態(tài)類型時合法,即該類至少具有一個虛擬方法。dynamic_cast與static_cast具有相同的基本語法,dynamic_cast重要用于類層次間的上行轉換和下行轉換,還可以用于類之間的交叉轉換。在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是同樣的;在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。如:classC{//…C沒有虛擬函數
};classT{
//…}?intmain()?{dynamic_cast<T*>(newC);//錯誤?}此時如改為以下則是合法的:?classC{?public:
virtualvoidm(){};//C現在是多態(tài)?}4.reinterpret_castinterpret是解釋的意思,reinterpret即為重新解釋,此標記符的意思即為數據的二進制形式重新解釋,但是不改變其值。如:inti;char*ptr="hellofreind!";i=reinterpret_cast<int>(ptr);這個轉換方式很少使用。33.分別寫出BOOL,int,float(yī),指針類型的變量a與“零”的比較語句。答案:
BOOL:if(!a)orif(a)
int:if(a==0)?float:constEXPRESSIONEXP=0.000001
if(a<EXP&&a>-EXP)floata;?constfloat(yī)eps=0.000001;?if((a>=-eps)&&(a<=eps))?pointer:if(a!=NULL)orif(a==NULL)34.請說出const與#define相比,有何優(yōu)點?答案:Const作用:定義常量、修飾函數參數、修飾函數返回值三個作用。被Const修飾的東西都受到強制保護,可以防止意外的變動,能提高程序的健壯性。1)const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查。而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換也許會產生意料不到的錯誤。
2)有些集成化的調試工具可以對const常量進行調試,但是不能對宏常量進行調試。35.簡述數組與指針的區(qū)別?數組要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局數組),要么在棧上被創(chuàng)建。指針可以隨時指向任意類型的內存塊。?(1)修改內容上的差別
chara[]=“hello”;
a[0]=‘X’;
char*p=“world”;//注意p指向常量字符串?p[0]=‘X’;//編譯器不能發(fā)現該錯誤,運營時錯誤?(2)用運算符sizeof可以計算出數組的容量(字節(jié)數)。sizeof(p),p為指針得到的是一個指針變量的字節(jié)數,而不是p所指的內存容量。C++/C語言沒有辦法知道指針所指的內存容量,除非在申請內存時記住它。注意當數組作為函數的參數進行傳遞時,該數組自動退化為同類型的指針。
chara[]="helloworld";
char*p=a;?cout<<sizeof(a)<<endl;//12字節(jié)
cout<<sizeof(p)<<endl;//4字節(jié)
計算數組和指針的內存容量
voidFunc(chara[100])?{
cout<<sizeof(a)<<endl;//4字節(jié)而不是100字節(jié)?}36.類成員函數的重載、覆蓋和隱藏區(qū)別?答案:a.成員函數被重載的特性:
(1)相同的范圍(在同一個類中);
(2)函數名字相同;?(3)參數不同;?(4)virtual關鍵字可有可無。?b.覆蓋是指派生類函數覆蓋基類函數,特性是:?(1)不同的范圍(分別位于派生類與基類);?(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有virtual關鍵字。?c.“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規(guī)則如下:
(1)假如派生類的函數與基類的函數同名,但是參數不同。此時,不管有無virtual關鍵字,基類的函數將被隱藏(注意別與重載混淆)。
(2)假如派生類的函數與基類的函數同名,并且參數也相同,但是基類函數沒有virtual關鍵字。此時,基類的函數被隱藏(注意別與覆蓋混淆)37.求出兩個數中的較大的一個;不用if,?:;switch或其他比較判斷Therearetwointvariables:aandb,don’tuse“if”,“?:”,“switch”orotherjudgementstatements,findoutthebiggestoneofthetwonumbers.答案:((a+b)+abs(a-b))/2假如a>b,那么a-b>0,所以表達式就變成了(a+b+a-b)/2=(a+a)/2=a。
假如a<b,那么a-b<0,取絕對值變成-(a-b),所以表達式變成了(a+b-a+b)/2=(b+b)/2=b。?總的來說就是取a和b中的最大值max。38.如何打印出當前源文獻的文獻名以及源文獻的當前行號?答案:
cout<<__FILE__;?cout<<__LINE__;
__FILE__和__LINE__是系統(tǒng)預定義宏,這種宏并不是在某個文獻中定義的,而是由編譯器定義的。39.main主函數執(zhí)行完畢后,是否也許會再執(zhí)行一段代碼,給出說明?答案:可以,可以用_onexit注冊一個函數,它會在main之后執(zhí)行intfn1(void),fn2(void),fn3(void),fn4(void);
voidmain(void)?{
Stringstr("zhanglin");
_onexit(fn1);
_onexit(fn2);?_onexit(fn3);
_onexit(fn4);
printf("Thisisexecutedfirst.n");?}?intfn1()?{?printf("next.n");?return0;?}?intfn2()
{
printf("executed");
return0;?}?intfn3()
{?printf("is");?return0;?}?intfn4()?{?printf("This");?return0;?}?The_onexitfunctionispassedtheaddressofafunction(func)tobecalledwhentheprogramterminatesnormally.Successivecallsto_onexitcreatearegisteroffunctionsthatareexecutedinLIFO(last-in-first-out)order.Thefunctionspassedto_onexitcannottakeparameters.40.如何判斷一段程序是由C編譯程序還是由C++編譯程序編譯的?答案:?#ifdef__cplusplus
cout<<"c++";
#else
cout<<"c";?#endif(1)假如是要你的代碼在編譯時發(fā)現編譯器類型,就判斷_cplusplus或_STDC_宏,通常許多編譯器尚有其他編譯標志宏,#ifdef__cpluspluscout<<"c++";#elsecout<<"c";#endif假如要判斷已經編譯的代碼的編譯類型,就用nm查一下輸出函數符號是否和函數名相同。(相同為c,不同為c++。詳解見下面)(2)簡樸是說,由于c語言是沒有重載函數的概念的,所以c編譯器編譯的程序里,所有函數只有函數名相應的入口。而由于c++語言有重載函數的概念,假如只有函數名相應的入口,則會出現混淆,所以c++編譯器編譯的程序,應當是函數名+參數類型列表相應到入口。注意,由于mian函數是整個程序的入口,所以mian是不能有重載的,所以,假如一個程序只有main函數,是無法確認是c還是c++編譯器編譯的可以通過nm來查看函數名入口如一個函數intfoo(inti,floatj)c編譯的程序通過nm查看foo0x567xxxxxx(地址)c++編譯程序,通過nm查看foo(int,float(yī))0x567xxxxxx此外,假如要在c++編譯器里使用通過c編譯的目的文獻,必須告知c++編譯器,我使用的函數是c風格的,不需要列出參數列表的,這樣c++編譯才干對的的連接41.文獻中有一組整數,規(guī)定排序后輸出到另一個文獻中?答案:#include<iostream>#include<vector>#include<fstream>usingnamespacestd;voidBubbleSort(vector<int>&array){for(inti=0;i!=array.size();i++){for(intj=array.size()-1;j!=i;j--){if(array[j]<array[j-1]){swap(array[j],array[j-1]);}}}}voidswap(int*a,int*b){inttemp;temp=*a;*a=*b;*b=temp;}voidmain(){vector<int>data;ifstreamin("c:\\dat(yī)a.txt");if(!in){cout<<"fileerror!"<<endl;exit(1);}inttemp;while(!in.eof()){in>>temp;data.push_back(temp);}in.close();BubbleSort(data);ofstreamout("c:\\result.txt");if(!out){cout<<"fileerror!"<<endl;exit(1);}for(inti=0;i<data.size();i++)out<<data[i]<<"";out.close();}42.鏈表題:一個鏈表的結點結構//與結構類型組合使用typedefstructtagMyStruct{intiNum;longlLength;}MyStruct;//(此處MyStruct為結構類型別名)=>structtagMyStruct{intiNum;longlLength;};//+typedefstructtagMyStructMyStruct;//結構中包含指向自己的指針用法typedefstructtagNode{char*pItem;pNodepNext;}*pNode;//=>error//1)typedefstructtagNode{char*pItem;structtagNode*pNext;}*pNode;//2)typedefstructtagNode*pNode;structtagNode{char*pItem;pNodepNext;};//3)規(guī)范structtagNode{char*pItem;structtagNode*pNext;};typedefstructtagNode*pNode;structNode
{?intdata;
Node*next;
};
typedefstructNodeNode;?(1)已知鏈表的頭結點head,寫一個函數把這個鏈表逆序(Intel)Node*ReverseList(Node*head)//鏈表逆序
{
if(head==NULL||head->next==NULL)
returnhead;?Node*p1=head;?Node*p2=p1->next;
Node*p3=p2->next;?p1->next=NULL;?while(p3!=NULL)?{
p2->next=p1;?p1=p2;
p2=p3;
p3=p3->next;?}?p2->next=p1;?head=p2;
returnhead;?}?(2)已知兩個鏈表head1和head2各自有序,請把它們合并成一個鏈表仍然有序。(保存所有結點,即便大小相同)
Node*Merge(Node*head1,Node*head2)
{
if(head1==NULL)?returnhead2;?if(head2==NULL)?returnhead1;?Node*head=NULL;?Node*p1=NULL;
Node*p2=NULL;
if(head1->data<head2->dat(yī)a)?{?head=head1;?p1=head1->next;
p2=head2;
}
else?{?head=head2;?p2=head2->next;
p1=head1;
}?Node*pcurrent=head;
while(p1!=NULL&&p2!=NULL)
{?if(p1->data<=p2->data)?{
pcurrent->next=p1;?pcurrent=p1;
p1=p1->next;?}?else
{?pcurrent->next=p2;
pcurrent=p2;?p2=p2->next;?}?}
if(p1!=NULL)?pcurrent->next=p1;
if(p2!=NULL)?pcurrent->next=p2;?returnhead;?}
(3)已知兩個鏈表head1和head2各自有序,請把它們合并成一個鏈表仍然有序,這次規(guī)定用遞歸方法進行。(Autodesk)?答案:?Node*MergeRecursive(Node*head1,Node*head2)
{
if(head1==NULL)
returnhead2;?if(head2==NULL)
returnhead1;?Node*head=NULL;
if(head1->data<head2->data)?{?head=head1;?head->next=MergeRecursive(head1->next,head2);
}?else?{?head=head2;
head->next=MergeRecursive(head1,head2->next);
}?returnhead;----------41.分析一下這段程序的輸出(Autodesk)
classB?{?public:?B()
{
cout<<"defaultconstructor"<<endl;?}?~B()
{
cout<<"destructed"<<endl;?}
B(inti):data(i)//B(int)worksasaconverter(int->instanceofB)?{
cout<<"constructedbyparameter"<<data<<endl;?}
privat(yī)e:?intdata;?};
BPlay(Bb)?{
returnb;
}(1)results:
intmain(intargc,char*argv[])constructedbyparameter5?{destructedB(5)形參析構?Bt1=Play(5);Bt2=Pl(wèi)ay(t1);destructedt1形參析構
return0;destructedt2注意順序!
}destructedt1(2)results:
intmain(intargc,char*argv[])constructedbyparameter5
{destructedB(5)形參析構?Bt1=Pl(wèi)ay(5);Bt2=Play(10);constructedbyparameter10?return0;destructedB(10)形參析構
}destructedt2注意順序?。鋏structedt143.寫一個函數找出一個整數數組中,第二大的數(microsoft)答案:
constintMINNUMBER=-32767;?intfind_sec_max(intdata[],intcount)?{
intmaxnumber=data[0];
intsec_max=MINNUMBER;
for(inti=1;i<count;i++)?{?if(data[i]>maxnumber)
{?sec_max=maxnumber;?maxnumber=dat(yī)a[i];?}?else
{?if(data[i]>sec_max)?sec_max=dat(yī)a[i];
}?}
returnsec_max;?}44.寫一個在一個字符串(n)中尋找一個子串(m)第一個位置的函數。KMP算法效率最佳,時間復雜度是O(n+m),#include<iostream>intSearch(char*Str,char*Sum){intl1=strlen(Str);intl2=strlen(Sum);if(l1-l2<0)//假如子串大于字符串長度直接返回return-1;inti;for(i=0;i<l1-l2;i++){intm=i;intj;for(j=0;j<l2;j++){if(Str[m]!=Sum[j])//有不匹配字符直接跳出break;m++;}if(j==l2)//找到匹配,跳出循環(huán)break;}returni<=l1-l2?i:-1;}voidmain(){charStr[15]="abdedabjlfdf";charSum[4]="aj";std::cout<<Search(Str,Sum);getchar();}46.多重繼承的內存分派問題:比如有classA:publicclassB,publicclassC{}那么A的內存結構大體是怎么樣的??這個是compiler-dependent的,不同的實現其細節(jié)也許不同。假如不考慮有虛函數、虛繼承的話就相稱簡樸;否則的話,相稱復雜??梢詤⒖肌哆M一步探索C++對象模型47.如何判斷一個單鏈表是有環(huán)的?(注意不能用標志位,最多只能用兩個額外指針)structnode{charval;node*next;}?boolcheck(constnode*head){}//returnfalse:無環(huán);true:有環(huán)一種O(n)的辦法就是(搞兩個指針,一個每次遞增一步,一個每次遞增兩步,假如有環(huán)的話兩者必然重合,反之亦然):
boolcheck(constnode*head)
{
if(head==NULL)returnfalse;?node*low=head,*fast=head->next;
while(fast!=NULL&&fast->next!=NULL)
{?low=low->next;
fast=fast->next->next;?if(low==fast)returntrue;
}?returnfalse;?}48.指針找錯題分析這些面試題,自身包含很強的趣味性;而作為一名研發(fā)人員,通過對這些面試題的進一步剖析則可進一步增強自身的內功。?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個字節(jié)才干存放下(涉及末尾的’\0’),而string只有10個字節(jié)的空間,strcpy會導致數組越界;對試題2,假如面試者指出字符數組str1不能在數組內結束可以給3分;假如面試者指出strcpy(string,str1)調用使得從str1內存起復制到string內存起所復制的字節(jié)數具有不擬定性可以給7分,在此基礎上指出庫函數strcpy工作方式的給10分;
對試題3,if(strlen(str1)<=10)應改為if(strlen(str1)<10),由于strlen的結果未記錄’\0’所占用的1個字節(jié)。剖析:考核對基本功的掌握
(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));
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)函數的形參為字符串指針,在函數內部修改形參并不能真正的改變傳入形參的值,執(zhí)行完
char*str=NULL;
GetMemory(str);
后的str仍然為NULL;試題5中?charp[]="helloworld";?returnp;?的p[]數組為函數內的局部自動變量,在函數返回后,內存已經被釋放。這是許多程序員常犯的錯誤,其根源在于不理解變量的生存期。?試題6的GetMemory避免了試題4的問題,傳入GetMemory的參數為字符串指針的指針,但是在GetMemory中執(zhí)行申請內存及賦值語句tiffanybracelets?*p=(char*)malloc(num);
后未判斷內存是否申請成功,應加上:
if(*p==NULL)?{?...//進行申請內存失敗解決
}?試題7存在與試題6同樣的問題,在執(zhí)行?char*str=(char*)malloc(100);
后未進行內存是否申請成功的判斷;此外,在free(str)后未置str為空,導致也許變成一個“野”指針,應加上:?str=NULL;?試題6的Test函數中也未對malloc的內存進行釋放。?剖析:
試題4~7考察面試者對內存操作的理解限度,基本功扎實的面試者一般都能對的的回答其中50~60的錯誤。但是要完全解答對的,卻也絕非易事。
對內存操作的考察重要集中在:?(1)指針的理解;?(2)變量的生存期及作用范圍;?(3)良好的動態(tài)內存申請和釋放習慣。?再看看下面的一段程序有什么錯誤:
以下是引用片段:?swap(int*p1,int*p2)
{?int*p;?*p=*p1;?*p1=*p2;
*p2=*p;
}
在swap函數中,p是一個“野”指針,有也許指向系統(tǒng)區(qū),導致程序運營的崩潰。在VC++中DEBUG運營時提醒錯誤“AccessViolation”。該程序應當改為
以下是引用片段:
swap(int*p1,int*p2)?{
intp;
p=*p1;?*p1=*p2;
*p2=p;
}50.String的具體實現已知String類定義如下:??classString?{
public:?String(constchar*str=NULL);//通用構造函數?String(constString&another);//拷貝構造函數
~String();//析構函數
String&operater=(constString&rhs);//賦值函數
private:
char*m_dat(yī)a;//用于保存字符串
};
?嘗試寫出類的成員函數實現。
答案:?String::String(constchar*str)?{?if(str==NULL)//strlen在參數為NULL時會拋異常才會有這步判斷?{?m_data=newchar[1];
m_data[0]='\0';
}
else
{?m_data=newchar[strlen(str)+1];
strcpy(m_data,str);
}?
}?
String::String(constString&another){?m_data=newchar[strlen(another.m_data)+1];?strcpy(m_data,other.m_data);
}
?String&String::operat(yī)or=(constString&rhs)?{?if(this==&rhs)?return*this;?delete[]m_data;//刪除本來的數據,新開一塊內存?m_data=newchar[strlen(rhs.m_dat(yī)a)+1];?strcpy(m_data,rhs.m_data);
return*this;?}???String::~String()?{
delete[]m_data;
}51.h頭文獻中的ifndef/define/endif的作用?答:防止該頭文獻被反復引用。52.#include<file.h>與#include"file.h"的區(qū)別?答:前者是從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++中的變量除支持局部變量外,還支持類成員變量和全局變量。用戶所編寫程序的類成員變量也許與全局變量同名,我們以"."來區(qū)分。而本質上,編譯器在進行編譯時,與函數的解決相似,也為類中的變量取了一個獨一無二的名字,這個名字與用戶程序中同名的全局變量名字不同。?
未加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的頭文獻變?yōu)椋?/p>
//模塊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.?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)void?b)short?c)int?d)Noneoftheabove?
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)1and8
b)8and4
c)4and8
d)8and1???第一個選C;?雖然傳入的是short類型,但是short類型的構造函數被生命被explicit,也就是只能顯示類型轉換,不能使用隱式類型轉換。
第二個選A;
第一個是指針加減,按照的是指向地址類型的加減,只跟類型位置有關,q和p指向的數據類型以實際數據類型來算差一個位置,因此是1。而第二個加減是實際指針值得加減,在內存中一個double類型占據8個字節(jié),因此是854.Sony筆試題?1.完畢下列程序
*
*.*.
*..*..*..?*...*...*...*...
*....*....*....*....*....
*.....
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年旅游產業(yè)借款合同規(guī)范文本3篇
- 相關課程綜合課程設計
- 戚風蛋糕的課程設計
- 幼兒園人體骨骼課程設計
- 2024年甲乙雙方關于專利申請代理的合同
- 探索世界插畫課程設計
- 2024年智能制造學徒工勞動培訓合同3篇
- 2024年自動化控制系統(tǒng)采購合同
- 智能密碼系統(tǒng)課程設計
- 2024年能效提升合同范本
- 國家開放大學法學本科《商法》歷年期末考試試題及答案題庫
- 金匱要略知到智慧樹章節(jié)測試課后答案2024年秋浙江中醫(yī)藥大學
- 【MOOC】有機化學實驗-南京工業(yè)大學 中國大學慕課MOOC答案
- 2024年婦??乒ぷ骺偨Y及計劃
- 北京理工大學《數據結構與算法設計》2022-2023學年第一學期期末試卷
- 錨桿(索)支護工技能理論考試題庫200題(含答案)
- 2024年公安機關理論考試題庫500道
- 2024年中國主題公園競爭力評價報告-中國主題公園研究院
- 2024年有限合伙股權代持
- 廣東珠海市駕車沖撞行人案件安全防范專題培訓
- 花城版一年級上冊音樂 第3課 《國旗國旗真美麗》(教案)
評論
0/150
提交評論