2023年經(jīng)典C面試題_第1頁
2023年經(jīng)典C面試題_第2頁
2023年經(jīng)典C面試題_第3頁
2023年經(jīng)典C面試題_第4頁
2023年經(jīng)典C面試題_第5頁
已閱讀5頁,還剩33頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1.簡介一下STL,詳細(xì)闡明STL怎樣實(shí)現(xiàn)vector。

STL(原則模版庫,StandardTemplateLibrai~y;它由容器算法迭代器構(gòu)成。

STL有如下日勺某些長處:

可以以便輕易地實(shí)現(xiàn)搜索數(shù)據(jù)或?qū)?shù)據(jù)排序等一系列H勺算法;

調(diào)試程序時(shí)愈加安全和以便;

雖然是人們用STL在UNIX平臺下寫的代碼你也可以很輕易地理解(由于STL是

跨平臺口勺)。

vector實(shí)質(zhì)上就是一種動態(tài)數(shù)組,會根據(jù)數(shù)據(jù)的增長,動態(tài)口勺增長數(shù)組空間。

2.假如用VC開發(fā)程序,常見這樣幾種錯(cuò)誤,C2O23,c2O23,c2O23,這些錯(cuò)誤的原因是什么。

在學(xué)習(xí)VC++的過程中,碰到日勺LNK2023錯(cuò)誤日勺錯(cuò)誤消息重要為:

unresolvedexternalsymbol"symbol”(不確定的外部"符號

假如連接程序不能在所有的庫和目H勺文獻(xiàn)內(nèi)找到所引用H勺函數(shù)、變量或標(biāo)簽,將產(chǎn)生此錯(cuò)誤

消息。

一般來說,發(fā)生錯(cuò)誤日勺原因有兩個(gè):?是所引用的函數(shù)、變量不存在、拼寫不對的或者使用

錯(cuò)誤;另一方面也許使用了不一樣版本的連接庫。

編程中常常能碰到LNK2O23錯(cuò)誤一一反復(fù)定義錯(cuò)誤,其實(shí)LNK2O23錯(cuò)誤并不是一種很難處理

的錯(cuò)誤.

3.繼承和委派有什么分別,在決定使用繼承或者委派的時(shí)候需要考慮什么。

在OODQOP中,組合優(yōu)于繼承.

當(dāng)然多態(tài)的基礎(chǔ)是繼承,沒有繼承多態(tài)無從談起。

當(dāng)對象的類型不影響類中函數(shù)日勺行為時(shí),就要使用模板來生成這樣?組類。

當(dāng)對象的類型影響類中函數(shù)的行為時(shí),就要使用繼承來得到這樣一組類.

4.指針和引用有什么分別;假如傳引用比傳指針安全,為何?假如我使用常量指針莫非不行

嗎?

(1)引用在創(chuàng)立"勺同步必須初始化,即引用到一種有效的對象;而指針在定義U勺時(shí)候不必初

始化,可以在定義背面日勺任何地方重新賦值.

(2)不存在NULL引用,引用必須與合法的存儲單元關(guān)聯(lián);而指針則可以是NULL.

(3)引用一旦被初始化為指向一種對象,它就不能被變化為另一種對象的引用:而指針在任

何時(shí)候都可以變化為指向另一種對象.給引用賦值并不是變化它和原始對象H勺綁定關(guān)系.

(4)引用的J創(chuàng)立和銷毀并不會調(diào)用類的拷貝構(gòu)造函數(shù)

(5)語言層面,引用的使用方法和對象同樣;在二進(jìn)制層面,引用一般都是通過指針來實(shí)現(xiàn)

的,只不過編譯器幫我們完畢了轉(zhuǎn)換.

不存在空引用,并且引用一旦被初始化為指向一種對象,它就不能被變化為另一種對象日勺引

用,顯得很安全。

const指針仍然存在空指針,并且有也許產(chǎn)生野指針.

總的來說:引用既具有指針的效率,又具有變量使用的以便性和直觀性.

5.參數(shù)傳遞有幾種方式;實(shí)現(xiàn)多態(tài)參數(shù)傳遞采用什么方式,假如沒有使用某種方式原因是什

么;

傳值,傳指針或者引用

6.結(jié)合一種項(xiàng)目闡明你怎樣應(yīng)用設(shè)計(jì)模式的理念。

設(shè)計(jì)模式更多考慮是擴(kuò)展和重用,而這兩方面諸多狀況下,往往會被忽視。

不過,我不提議濫用設(shè)計(jì)模式,認(rèn)為它有也許使得簡樸問題復(fù)雜化.

7.簡介一下你對設(shè)計(jì)模式的理解。(這個(gè)過程中有諸多很細(xì)節(jié)的問題隨機(jī)問的)

設(shè)計(jì)模式概念是由建筑設(shè)計(jì)師ChristopherAlexander提出:“每一種模式描述了一種在我們周

圍不停反復(fù)發(fā)生II勺問題,以及該問題U勺處理方案U勺關(guān)鍵.這樣,你就能一次又一次地使用該方

案而不必做反復(fù)勞動上述定義是對設(shè)計(jì)模式的廣義定義.將其應(yīng)用到面向?qū)Α鱿筌浖念I(lǐng)域

內(nèi),就形成了對設(shè)計(jì)模式的狹義定義.

可以簡樸H勺認(rèn)為:設(shè)計(jì)模式就是處理某個(gè)特定的面向?qū)ο筌浖栴}的特定措施,并且已經(jīng)上

升到理論程度。

框架與設(shè)計(jì)模式口勺區(qū)別:

1,設(shè)計(jì)模式和框架針對煙問題域不一樣.設(shè)計(jì)模式針對面向?qū)ο罂谏讍栴}域;框架針對特定業(yè)務(wù)

的問題域

2,設(shè)計(jì)模式比框架更為抽象.設(shè)計(jì)模式在碰到詳細(xì)問題后,才能產(chǎn)生代碼;框架已經(jīng)可以用代碼

表達(dá)

3,設(shè)計(jì)模式是比框架更小的體系構(gòu)造元素.框架中可以包括多種設(shè)計(jì)模式

設(shè)計(jì)模式就像武術(shù)中基本的招式.將這些招式合理地縱組合起來,就形成套路(框架),框架是

一種半成品.

8.C++和C定義構(gòu)造的分別是什么。

Clanguage的構(gòu)造僅僅是數(shù)據(jù)的結(jié)合

Cplusplusstruct和class其實(shí)具有幾乎同樣的功能,只是默認(rèn)日勺訪問屬性不一樣樣而己。

9.構(gòu)造函數(shù)可否是虛汗數(shù),為何?析構(gòu)函數(shù)呢,可否是純虛的呢?

構(gòu)造函數(shù)不能為虛函數(shù),要構(gòu)造一種對象,必須清晰地情得要構(gòu)造什么,否則無法構(gòu)造一種

對象。

析構(gòu)函數(shù)可認(rèn)為純虛函數(shù),

10.拷貝構(gòu)造函數(shù)有關(guān)問題,深拷貝,淺拷貝,臨時(shí)對象等。

深拷貝意味著拷貝了資源和指針,而淺拷貝只是拷貝了指針,沒有拷貝資源

這樣使得兩個(gè)指針指向同一份資源,導(dǎo)致對同一份析構(gòu)兩次,程序瓦解。

臨時(shí)對象的開銷比局部對象小些.

11.結(jié)合1個(gè)你認(rèn)為比較能體現(xiàn)OOP思想的項(xiàng)目,用UML來描述。

(最佳這個(gè)項(xiàng)目繼承,多態(tài),虛函數(shù)均有體現(xiàn))這個(gè)問題大概會占面試時(shí)間的二分之一,并且

會問諸多問題,一不小心也許會被問?。?/p>

12.基類口勺有1個(gè)虛函數(shù),子類還需要申明為virtual嗎?為何。

不申明沒有關(guān)系FI勺。

不過,我總是喜歡顯式申明,使得代碼愈加清晰。

13.C也可以通過精心封裝某些函數(shù)功能實(shí)現(xiàn)重用,那CH的類有什么長處嗎,莫非僅僅是為

實(shí)現(xiàn)重用。

并不僅僅是這樣口勺。

00D,OOP從主線上變化了程序設(shè)計(jì)模式和設(shè)計(jì)思想,具有重大和深遠(yuǎn)的意義。

類的三大最基本口勺特性:封裝,繼承,多態(tài).

14.C++特點(diǎn)是什么,怎樣實(shí)現(xiàn)多態(tài)?畫出基類和子類在內(nèi)存中的互相關(guān)系。

多態(tài)的基礎(chǔ)是繼承,需要虛函數(shù)的支持,簡樸日勺多態(tài)是很簡樸的I。

子類繼承父類大部分的資源,不能繼承H勺有構(gòu)造函數(shù),析構(gòu)函數(shù),拷貝構(gòu)造函數(shù),operator:

函數(shù),友元函數(shù)等等

15.為何要引入抽象基類和純虛函數(shù)?

重要目的是為了實(shí)現(xiàn)一種接口的效果。

16.簡介一下模板和容器。怎樣實(shí)現(xiàn)?(也許會讓你當(dāng)場舉例實(shí)現(xiàn))

模板可以說比較古老了,不過Fl前的泛型編程實(shí)質(zhì)上就是模板編程。

它體現(xiàn)了一種通用和泛化的思想。

STL有7種重要容器:vector,list,deque,map,multimap,set,multiset.

17.你怎樣理解MVC。簡樸舉例來闡明其應(yīng)用。

MVC模式是observer模式的一種特例,經(jīng)典的有MFC里面H勺文檔視圖架構(gòu)。

18.多重繼承怎樣消除向上繼承的二義性。

使用虛擬繼承即可.

1.如下三條輸出語句分別輸出什么?(C易]

charstrl[]="abc”;

charstr2[]="abc”;

constcharstr3[]="abc”;

constcharstr4[]="abc";

constchar*str5="abc”;

constchar*str6="abc”;

cout?boolalpha?(strl==str2)?endl;//輸出什么?

cout?boolalpha?(str3==str4)?endl;//輸出什么?

cout?boolalpha?(str5==str6)?endl;//輸出什么?

2.非C++內(nèi)建型別A和B,在哪幾種狀況下B能隱式轉(zhuǎn)化為A?[C++中等]

答:

a.classB:publicA{……}〃B公有繼承自A,可以是間接繼承日勺

b.classB{operatorA();}//B實(shí)現(xiàn)了隱式轉(zhuǎn)化為A的轉(zhuǎn)化

c.classA{A(constB&);}//A實(shí)現(xiàn)了non-explicit的參數(shù)為B(可以有其他帶默認(rèn)值的參數(shù))

構(gòu)造函數(shù)

d.A&operator=(constA&);〃賦值操作,雖不是正宗時(shí)隱式類型轉(zhuǎn)換,但也可以勉強(qiáng)算一種

3.如下代碼中的兩個(gè)sizeof使用方法有問題嗎?[C易]

voidUpperCasefcharstr[])//將str中U勺小寫字母轉(zhuǎn)換成大寫字母

{

for(size_ti=0;i

if('a'<=str[i]&&str[i]<='z')

str[i]-=('a'-'A');

)

charstr[]="aBcDe";

cout?"str字符長度為:"?sizeof(str)/sizeof(str[0])?endl;

UpperCase(str);

cout?str?endl;

1.求下面函數(shù)日勺返回值(微軟)

intfunc(x)

(

intcountx=0;

while(x)

{

countx++;

x=x&(x-l);

}

returncountx;

)

假定x=9999。答案:8

思緒:將x轉(zhuǎn)化為2進(jìn)制,看具有的1H勺個(gè)數(shù)。

2.什么是“引用”?申明和使用“引用”要注意哪些問題?

答:引用就是某個(gè)目的變量的“別名”(alias),對應(yīng)用R勺操年與對變量直接操作效果完全相似。

申明一種引用U勺時(shí)候,牢記要對其進(jìn)行初始化。引用申明完畢后,相稱于忖的變量名有兩個(gè)

名稱,即該目的原名稱和引用名,不能再把該引用名作為其他變最名日勺別名。申明一種引用,

不是新定義了一種變量,它只表達(dá)該引用名是目的變量名的一種別名,它自身不是一種數(shù)

據(jù)類型,因此引用自身不占存儲單元,系統(tǒng)也不給引用分派存儲單元。不能建立數(shù)組的引用。

3.將“引用”作為函數(shù)參數(shù)有哪些特點(diǎn)?

(1)傳遞引用給函數(shù)與傳遞指針的效果是同樣II勺。這時(shí),被調(diào)函數(shù)II勺形參就成為本來主調(diào)

函數(shù)中歐I實(shí)參變量或?qū)ο蟮囊环N別名來使用,因此在被調(diào)函數(shù)中對形參變星的J操作就是對

其對應(yīng)的目的對象(在主調(diào)函數(shù)中)的操作。

(2)使用引用傳遞函數(shù)的參數(shù),在內(nèi)存中并沒有產(chǎn)生實(shí)參的副本,它是直接對實(shí)參操作;而

使用一般變量傳遞函數(shù)H勺參數(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á)與使用引用II勺效果,不過,在被調(diào)函數(shù)中同樣要

給形參分派存儲單元,且需要反復(fù)使用”*指針變量名啜J股式進(jìn)行運(yùn)算,這很輕易產(chǎn)生錯(cuò)誤

且程序的閱讀性較差;另首先,在主調(diào)函數(shù)的調(diào)用點(diǎn)處,必須用變量U勺地址作為實(shí)參。而引

用更輕易使用,更清晰。

4.在什么時(shí)候需要使用“常引用”?

假如既要運(yùn)用引用提高程序H勺效率,又要保護(hù)傳遞給函數(shù)的數(shù)據(jù)不在函數(shù)中被變化,就應(yīng)使

用常引用。常引用申明方式:const類型標(biāo)識符&引用名=目的變量名;

例1

inta;

constint&ra=a;

ra=l;〃錯(cuò)誤

a=l;〃對的

例2

stringfoo();

voidbar(string&s);

那么下面的體現(xiàn)式將是非法的:

bar(foo());

bar("helloworld");

原因在于foo()和“helloworld”串都會產(chǎn)生一種臨時(shí)對象,而在C++中,這些臨時(shí)對象都是

const類型口勺。因此上面的體現(xiàn)式就是試圖將一種const類型日勺對象轉(zhuǎn)換為非const類型,這

是非法的。

引用型參數(shù)應(yīng)當(dāng)在能被定義為const的狀況下,盡量定義為const。

5.將“引用”作為函數(shù)返回值類型H勺格式、好處和需要遵守的規(guī)則?

格式:類型標(biāo)識符&函數(shù)名(形參列表及類型闡明){〃函數(shù)體}

好處:在內(nèi)存中不產(chǎn)生被返回值口勺副本;(注意:正是由于這點(diǎn)原因,因此返回一種局部變

量的引用是不可取的。由于伴隨該局部變量生存期的結(jié)束,對應(yīng)的引用也會失效,產(chǎn)生

runtimeerror!

注意事項(xiàng):

(1)不能返回局部變量的引用。這條可以參照EffectiveC++[l腑Item31。重要原因是局部

變量會在函數(shù)返回后被銷毀,因此被返回的引用就成為了”無所指叩勺引用,程序會進(jìn)入未知

狀態(tài)。

(2)不能返回函數(shù)內(nèi)部new分派W、J內(nèi)存口勺引用。這條可以參照EffectiveC++[1]RZ'JItem31”

雖然不存在局部變量時(shí)被動銷毀問題,可對于這種狀況(返回函數(shù)內(nèi)部new分派內(nèi)存的引

用),又面臨其他尷尬局面。例如,被函數(shù)返回的引用只是作為一種臨時(shí)變量出現(xiàn),而沒有

被賦予一種實(shí)際口勺變量,那么這個(gè)引用所指向的空間(由new分派)就無法釋放,導(dǎo)致

memoryleak。

(3)可以返回類組員的I引用,但最佳是const。這條原則可以參照EffectiveC++[l]09Item30。

重要原因是當(dāng)對象的屬性是與某種業(yè)務(wù)規(guī)則(businessMe)有關(guān)聯(lián)的時(shí)候,其賦值常常與

某些其他屬性或者對?象的狀態(tài)有關(guān),因此有必要將賦值操作封裝在一種業(yè)務(wù)規(guī)則當(dāng)中。假

如其他對象可以獲得該屬性U勺非常量引用(或指針),那么對該屬性的單純賦值就會破壞業(yè)

務(wù)規(guī)則的完整性。

(4)流操作符重載返回值申明為“引用”口勺作用:

流操作符<<和>>,這兩個(gè)操作符常常但愿被持續(xù)使用,例如:cout?"hello"?endl;因此

這兩個(gè)操作符口勺返回值應(yīng)當(dāng)是一種仍然支持這兩個(gè)操作符的流引用??蛇x時(shí)其他方案包括:

返回一種流對象和返回一種流對象指針。不過對于返回一種流對象,程序必須重新(拷貝)

構(gòu)造一種新的流對象,也就是說,持續(xù)的J兩個(gè)<<操作符實(shí)際上是針對不一樣對象的!這無

法讓人接受。對于返回一種流指針則不能持續(xù)使用<<操作符。因此,返回一種流對象引用是

惟一選擇。這個(gè)唯一選擇很關(guān)健,它闡明了引用的重要性以及無可替代性,也許這就是C++

語言中引入引用這個(gè)概念的原因吧。賦值操作符?這個(gè)操作符象流操作符同樣,是可以持

續(xù)使用的,例如:x=j=10;或者(x=10)=100;賦值操作符的返回值必須是一種左值,以便可以

被繼續(xù)賦值。因此引用成了這個(gè)操作符的惟一返回值選擇。

例3

ttinclude

int&put(intn);

intvals[10);

interror=-l;

voidmain()

|

put(0)=10;〃以put(O)函數(shù)值作為左值,等價(jià)于vals[0]=10;

put(9)=20;〃以put⑼函數(shù)值作為左值,等價(jià)于vals⑼=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++[l]隹)Item23詳細(xì)的討論了這個(gè)問題。重要原因是這四個(gè)操作符沒有sideeffect,

因此,它們必須構(gòu)造一種對象作為返回值,可選H勺方案包括:返回一種對象、返回一個(gè)局

部變量的引用,返回一種new分派的對象的引用、返回一種靜態(tài)對象引用。根據(jù)前面提到

的引用作為返回值的I三個(gè)規(guī)則,第2、3兩個(gè)方案都被否決了。靜態(tài)對象的J引用又由于((a+b)

==(c+d))會永遠(yuǎn)為true而導(dǎo)致錯(cuò)誤。因此可選H勺只剩余返回一種對象了。

6.引用與多態(tài)日勺關(guān)系?

引用是除指針外另一種可以產(chǎn)生多態(tài)效果的手段。這意味著,一種基類日勺引用可以指向它口勺

派生類實(shí)例。

例4

ClassA;ClassB:ClassBb;A&ref=b;

7.引用與指針的區(qū)別是什么?

指針通過某個(gè)指針變量指向一種對象后,對它所指向的變量間接操作。程序中使用指針,程

序的可讀性差;而引用自身就是忖的變量的別名,對引用U勺操作就是對目的變量的操作。此

外,就是上面提到日勺對函數(shù)傳ref和pointer09區(qū)別。

8.什么時(shí)候需要“引用”?

流操作符《和>>、賦值操作符=的返回值、拷貝構(gòu)造函數(shù)歐I參數(shù)、賦值操作符=的參數(shù)、其他

狀況都推薦使用引用</val$[9];

</vals[0];

1.如下三條輸出語句分別輸出什么?[C易]

charstrl[]="abc”;

charstr2[]="abc”;

constcharstr3[]=“abc”;

constcharstr4[]="abc”;

constchar*str5=“abc”;

constchar*str6="abc”;

cout?boolalpha?(strl==str2)?endl;//輸出什么?

cout?boolalpha?(str3==str4)?endl;//輸出什么?

cout?boolalpha?(str5==str6)?endl;//輸出什么?

2.非C++內(nèi)建型別A和B,在哪幾種狀況下B能隱式轉(zhuǎn)化為A?[C++中等]

答:

a.classB:publicA{……}//B公有繼承自A,可以是間接繼承的

b.classB{operatorA();}//B實(shí)現(xiàn)了隱式轉(zhuǎn)化為A的J轉(zhuǎn)化

c.classA{A(constB&);}//A實(shí)現(xiàn)了non-explicit的參數(shù)為B(可以有其他帶默認(rèn)值的參數(shù))

構(gòu)造函數(shù)

d.A&operator=(constA&);11賦值操作,雖不是正宗的隱式類型轉(zhuǎn)換,但也可以勉強(qiáng)算一種

3.如下代碼中的兩個(gè)sizeof使用方法有問題嗎?[C易]

voidUpperCasefcharstr(])//將str中日勺小寫字母轉(zhuǎn)換成大寫字母

(

for(size_ti=0;i

if('a'<=str[i]&&str[i]<='z')

str(i]-=('a'-'A');

)

charstr[]="aBcDe";

cout?"str字符長度為:"?sizeof(str)/sizeof(str[OJ)?endl;

UpperCase(str);

cout?str?endl;

1.求下面函數(shù)H勺返回值(微軟)

intfunc(x)

{

intcountx=0;

while(x)

(

countx++;

x=x&(x-l);

}

returncountx;

)

假定x=9999。答案:8

思緒:將x轉(zhuǎn)化為2進(jìn)制,看具有的1FI勺個(gè)數(shù)。

2.什么是“引用”?申明和使用“引用”要注意哪些問題?

答:引用就是某個(gè)目的變量的“別名”(alias),對應(yīng)用的操作與對變量直接操作效果完全相似。

申明一種引用U勺時(shí)候,牢記要對其進(jìn)行初始化。引用申明完畢后,相稱于忖的變量名有兩個(gè)

名稱,即該目的原名稱和引用名,不能再把該引用名作為其他變量名口勺別名。申明一種引用,

不是新定義了一種變量,它只表達(dá)該引用名是目的變量名的一種別名,它自身不是一種數(shù)

據(jù)類型,因此引用自身不占存儲單元,系統(tǒng)也不給引用分派存儲單元。不能建立數(shù)組的引用。

3.將“引用”作為函數(shù)參數(shù)有哪些特點(diǎn)?

(1)傳遞引用給函數(shù)與傳遞指針的效果是同樣日勺。這時(shí),被調(diào)函數(shù)的形參就成為本來主調(diào)

函數(shù)中的實(shí)參變量或?qū)ο蟮腎一種別名來使用,因此在被調(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í)參變最的副本:假如傳遞H勺是對?象,還將調(diào)用拷貝構(gòu)造函數(shù)。因此,當(dāng)參數(shù)傳遞歐數(shù)據(jù)

較大時(shí),用引用比用一般變量傳遞參數(shù)的效率和所占空間都好。

(3)使用指針作為函數(shù)的參數(shù)雖然也能到達(dá)與使用引用H勺效果,不過,在被調(diào)函數(shù)中同樣要

給形參分派存儲單元,且需要反復(fù)使用”*指針變量名”的形式進(jìn)行運(yùn)算,這很輕易產(chǎn)生錯(cuò)誤

且程序的閱讀性較差;另首先,在主調(diào)函數(shù)的調(diào)用點(diǎn)處,必須用變量的)地址作為實(shí)參。而引

用更輕易使用,更清晰。

4.在什么時(shí)候需要使用“常引用”?

假如既要運(yùn)用引用提高程序H勺效率,又要保護(hù)傳遞給函數(shù)的I數(shù)據(jù)不在函數(shù)中被變化,就應(yīng)使

用常引用。常引用申明方式:const類型標(biāo)識符&引用名=目的變量名;

例1

inta;

constint&ra=a;

ra=l;〃錯(cuò)誤

a=l;〃對的

例2

stringfoo();

voidbar(string&s);

那么下面的體現(xiàn)式將是非法的:

bar(foo());

bar("helloworld");

原因在于foo()和“helloworld”串都會產(chǎn)生一種臨時(shí)對象,而在C++中,這些臨時(shí)對象都是

const類型日勺。因此上面的體現(xiàn)式就是試圖將一種const類型口勺對象轉(zhuǎn)換為非const類型,這

是非法的。

引用型參數(shù)應(yīng)當(dāng)在能被定義為const的狀況下,盡量定義為const。

5.將“引用”作為函數(shù)返回值類型口勺格式、好處和需要遵守的規(guī)則?

格式:類型標(biāo)識符&函數(shù)名(形參列表及類型闡明){〃函數(shù)體}

好處:在內(nèi)存中不產(chǎn)生被返回值口勺副本;(注意:正是由于這點(diǎn)原因,因此返回一種局部變

量U勺引用是不可取"勺。由于伴隨該局部變量生存期的結(jié)束,對應(yīng)的引用也會失效,產(chǎn)生

runtimeerror!

注意事項(xiàng):

(1)不能返回局部變量的引用。這條可以參照EffectiveC++⑴的Item31。重要原因是局部

變量會在函數(shù)返回后被銷毀,因此被返回的引用就成為了“無所指叩勺引用,程序會進(jìn)入未知

狀態(tài)。

(2)不能返回函數(shù)內(nèi)部new分派的J內(nèi)存的I引用。這條可以參照EffectiveC++[1]0;JItem31.

雖然不存在局部變量時(shí)被動銷毀問題,可對于這種狀況(返回函數(shù)內(nèi)部new分派內(nèi)存的引

用),又面臨其他尷尬局面。例如,被函數(shù)返回的引用只是作為一種臨時(shí)變量出現(xiàn),而沒有

被賦予一種實(shí)際的變量,那么這個(gè)引用所指向的空間(由new分派)就無法釋放,導(dǎo)致

memoryleak。

(3)可以返回類組員的引用,但最佳是const。這條原則可以參照EffectiveC++⑴的Item30。

重要原因是當(dāng)對象的屬性是與某種業(yè)務(wù)規(guī)則(businessrule)有關(guān)聯(lián)的時(shí)候,其賦值常常與

某些其他屬性或者對象的狀態(tài)有關(guān),因此有必要將賦值操作封裝在一種業(yè)務(wù)規(guī)則當(dāng)中。假

如其他對象可以獲得該屬性II勺非常量引用(或指針),那么對該屬性的單純賦值就會破壞業(yè)

務(wù)規(guī)則的完整性。

(4)流操作符重載返回值申明為“引用”的作用:

流操作符《和》,這兩個(gè)操作符常常但愿被持續(xù)使用,例cout?"hello"?endl;因此

這兩個(gè)操作符口勺返回值應(yīng)當(dāng)是一種仍然支持這兩個(gè)操作符的流引用。可選的其他方案包括:

返回一種流對象和返回一種流對象指針。不過對于返回一種流對象,程序必須重新(拷貝)

構(gòu)造一種新H勺流對象,也就是說,持續(xù)的兩個(gè)<<操作符實(shí)際上是針對不一樣對象的!這無

法讓人接受。對于返回?種流指針則不能持續(xù)使用<<操作符。因此,返回?種流對象引用是

惟一選擇。這個(gè)唯一選擇艱關(guān)鍵,它闡明了引用的重要性以及無可替代性,也許這就是C++

語言中引入引用這個(gè)概念的原因吧。賦值操作符?這個(gè)操作符象流操作符同樣,是可以持

續(xù)使用的,例如I:x=j=l();或者(x=10)=100;賦值操作符『'J返回值必須是一種左值,以便可以

被繼續(xù)賦值。因此引用成了這個(gè)操作符的惟一返回值選擇。

例3

#include

int&put(intn);

intvals[10];

interror=-l;

voidmain()

(

put(0)=10;〃以put(O)函數(shù)值作為左值,等價(jià)于vals(0]=10;

puH9)=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++[l]li勺Item23詳細(xì)的討論J’這個(gè)問題。重要原因是這四個(gè)操作符沒有sideeffect,

因此,它們必須構(gòu)造一種對象作為返回值,可選H勺方案包括:返回一種對象、返回一個(gè)局

部變量的引用,返回一種new分派的對象"勺引用、返回一種靜態(tài)對象引用。根據(jù)前面提到

的I引用作為返回值的三個(gè)規(guī)則,第2、3兩個(gè)方案都被否決了。靜態(tài)對象的J引用又由于((a+b)

==(c+d))會永遠(yuǎn)為true而導(dǎo)致錯(cuò)誤。因此可選H勺只剩余返回一種對象了。

6.引用與多態(tài)日勺關(guān)系?

引用是除指針外另一種可以產(chǎn)生多態(tài)效果的手段。這意味著,一種基類目勺引用可以指向它日勺

派生類實(shí)例。

例4

ClassA;ClassB:ClassBb;A&ref=b;

7.引用與指針的I區(qū)別是什么?

指針通過某個(gè)指針變量指向一種對象后,對它所指向的變量間接操作。程序中使用指針,程

序的可讀性差:而引用自身就是目的變量的I別名,對引用H勺操作就是對目日勺變量的操作。此

外,就是上面提到口勺對函數(shù)傳ref和pointerH勺區(qū)別。

8.什么時(shí)候需要“引用”?

流操作符<<和>>、賦值操作符=的返回值、拷貝構(gòu)造函數(shù)的參數(shù)、賦值操作符=時(shí)參數(shù)、其他

狀況都推薦使用引用</vals[9];

</vals[0];

1)什么是預(yù)編譯,何時(shí)需要預(yù)編譯:總是使用不常常改動H勺大型代碼體。

程序由多種模塊構(gòu)成,所有模塊都使用?組原則的包括文獻(xiàn)和相似的編譯選項(xiàng)。在這種狀況

下,可以將所有包括文獻(xiàn)預(yù)編譯為一種預(yù)編譯頭。

2)char*constp;

charconst*p

constchar*p

上述三個(gè)有什么區(qū)別?

char*constp;〃常量指針,pH勺值不可以修改

charconst*p;〃指向常量口勺指針,指向時(shí)常量值不可以改

constchar*p;〃和charconst*p

3)charstrl[]="abc”;

charstr2[]="abc”;

constcharstr3[]="abc";

constcharstr4[]=“abc”;

constchar*str5=“abc”;

constchar*str6=“abc”;

char*str7="abc”;

char*str8="abc”;

cout?(strl==str2)?endl;

cout?(str3==str4)?endl;

cout?(str5==str6)?endl;

cout?(str7==str8)?endl;

成果是:0011

解答:strl,str2,str3,str4是數(shù)組變量,它們有各自的內(nèi)存空間;而str5,str6,str7,str8是指

針,它們指向相似的常量區(qū)域。

4)如下代碼中的I兩個(gè)sized使用方法有問題嗎?

voidUpperCase(charstr[])//將str中U勺小寫字母轉(zhuǎn)換成大寫字母

(

for(size_ti=0;i

if('a'<=str[i]&&str[i]<='z')

str[i]-=('a'-'A');

)

charstr[]="aBcDe";

cout?"str字符長度為:"?sizeof(str)/sizeof(str[0])?endl;

UpperCase(str);

cout?str?endl;

答:函數(shù)內(nèi)日勺sizeof有問題。根據(jù)語法,sizeof如用于數(shù)組,只能測出靜態(tài)數(shù)組日勺大小,無法

檢測動態(tài)分派H勺或外部數(shù)組大小。函數(shù)外的str是一種靜態(tài)定義的數(shù)組,因此其大小為6,函

數(shù)內(nèi)的str實(shí)際只是一種指向字符串的指針,沒有任何額外的與數(shù)組有關(guān)的信息,因此sizeof

作用于上只將其當(dāng)指針看,一種指針為4個(gè)字節(jié),因此返回4。

5)一種32位的機(jī)器,該機(jī)器的指針是多少位?

指針是多少位只要看地址總線口勺位數(shù)就行了。80386后來打勺機(jī)子都是32的數(shù)據(jù)總線。因此

指針的位數(shù)就是4個(gè)字節(jié)了。

6)main()

inta[5]={l,2,3,4,5};

int*ptr=(int*)(&a+l);

printf("%d/%d",*(a+l),*(ptr-l));

)

輸出:2,5

?(a+1)就是a[l],*(ptr?l)就是a⑷,執(zhí)行成果是2,5

&a+l不是首地址+1,系統(tǒng)會認(rèn)為加一種a數(shù)組的偏移,是偏移了一種數(shù)組的大小(本例

是5個(gè)int)

int*ptr=(int*)(&a+l);

則ptr實(shí)際是&(a[5]),也就是a+5

原因如下:

&a是數(shù)組指針,其類型為int(*)(5];

而指針加1要根據(jù)指針類型加上一定的值,不一樣類型日勺指針+1之后增長的大小不一

樣。

a是長度為5的int數(shù)組指針,因此要加5*sizeof(int)

因此ptr實(shí)際是a[5]

不過prt與(&a+l)類型是不?樣樣的(這點(diǎn)很重要)

因此prt-1只會減去sizeoffint*)

a,&aU勺地址是同樣的,但意思不一樣樣,a是數(shù)組首池址,也就是a⑼的地址,&a是對象

(數(shù)組)首地址,a+1是數(shù)組下一元素的地址,即a[l],&a+l是下一種對象的地址,即a[5].

7)請問如下代碼有什么問題:

intmain()

(

chara;

char*str=&a;

strcpy(str;'hello");

printf(str);

return0;

)

沒有為str分派內(nèi)存空間,將會發(fā)生異常。問題出在將一種字符串夏制進(jìn)一種字符變量

指針?biāo)傅刂?。雖然可以對的輸出成果,但由于越界進(jìn)行內(nèi)在讀寫而導(dǎo)致程序瓦解。

8)

char*s="AAA";

printf(”%s,s);

s[0]='B';

printf("%s”,s);

有什么錯(cuò)?

"AAA”是字符串常量。s是指針,指向這個(gè)字符串常量,因此申明s的時(shí)候就有問題。

cosntchar*s="AAA";

然后又由于是常量,因此對是s[0"勺賦值操作是不合法的。

9)寫一種“原則”宏,這個(gè)宏輸入兩個(gè)參數(shù)并返回較小的一種。

,#defineMin(X,Y)((X)>(Y)?(Y):(X))〃結(jié)尾沒有;

10)嵌入式系統(tǒng)中常常要用到無限循環(huán),你怎么用C編寫死循環(huán)。

while(l){}或者for(;;)

軟件開發(fā)網(wǎng)

11)關(guān)鍵字static的作用是什么?

定義靜態(tài)變量

12)關(guān)鍵字const有什么含意?

表達(dá)常量不可以修改的變量。

13)關(guān)鍵字volatile有什么含意?并舉出三個(gè)不一樣的例子?

提醒編譯相對象的值也許在編譯器未監(jiān)測到的狀況下變化。

14)int(?s[10])(int)表達(dá)的是什么?

int(*s[10])(int)函數(shù)指針數(shù)組,每個(gè)指針指向一種intfunc(intparam附函數(shù)。

15)有如下體現(xiàn)式:

inta=248;b=4;

intconstc=21;

constint*d=&a;

int*conste=&b;

intconst*fconst=&a;

請問下列體現(xiàn)式哪些會被編譯器嚴(yán)禁?為何?

*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;

*c這是個(gè)什么東東,嚴(yán)禁

*d說了是const,嚴(yán)禁

e=&a說了是const嚴(yán)禁

const*fconst-&a;嚴(yán)禁

16)互換兩個(gè)變量H勺值,不使用第三個(gè)變量。即a=3,b=5,互換之后a=5,b=3;

有兩種解法,一種用算術(shù)算法,一種用人(異或)

a=a+b;

b=a-b;

a=a-b;

or

a=aAb;//只能對int,:har..

b=aAb;

a=aAb;

or

aA=bA=a;

17)c和C++中U勺struct有什么不一樣?

c和C++中struct的重要區(qū)別是c中的Istruct不可以具有組員函數(shù),而C++中/gstruct可

以。C++中struct和class的重要區(qū)別在于默認(rèn)歐I存取權(quán)限不一樣,struct默認(rèn)為public,而class

默認(rèn)為privateo

18)#include

//include

voidgetmemory(char*p)

(

p=(char*)malloc(lOO);

M

strcpy(p/^^helloworld);

)

intmain()

(

char*str=NULL;

getmemory(str);

printf(u%s/nM,str);

free(str);

return0;

程序瓦解,getmemory中日勺malloc不能返回動態(tài)內(nèi)存,free()對str操作很危瞼

19)charszstr[10];

strcpy(szstr,"");

產(chǎn)生什么成果?為何?

長度不一樣樣,會導(dǎo)致非法U勺OS

20)列舉幾種進(jìn)程日勺同步機(jī)制,并比較其優(yōu)缺陷。

原子操作、信號量機(jī)制、自旋鎖、管程,會合,分布式系統(tǒng)

21)進(jìn)程之間通信H勺途徑

1.管道2.信號3.消息隊(duì)列4.共享內(nèi)存

22)進(jìn)程死鎖的原因

(1)競爭資源

(2)進(jìn)程推進(jìn)次序不妥

23)死鎖的4個(gè)必要條件

互斥、部分分派、不可剝奪、循環(huán)

24)死鎖時(shí)處理

鴕鳥方略、防止方略、防止方略、檢測與解除死鎖

25)操作系統(tǒng)中進(jìn)程調(diào)度方略有哪幾種?

FCFS(先來先服務(wù)),優(yōu)先級,時(shí)間片輪轉(zhuǎn),多級反饋

26)類的靜態(tài)組員和非靜態(tài)組員有何區(qū)別?

類的靜態(tài)組員每個(gè)類只有一種,非靜態(tài)組員每個(gè)對象一種

27)純虛函數(shù)怎樣定義?使用時(shí)應(yīng)注意什么?

virtualvoidf()=0;

是接口,子類必須要實(shí)現(xiàn)

28)數(shù)組和鏈表的區(qū)別

數(shù)組:數(shù)據(jù)次序存儲,固定大小

連表:數(shù)據(jù)可以隨機(jī)存儲,大小可動態(tài)變化

29)ISO的七層模型是什么?tcp/udp是屬于哪一層?tcp/udp有何優(yōu)缺陷?

應(yīng)用層

表達(dá)層

會話層

運(yùn)送層

網(wǎng)絡(luò)層

物理鏈路層

物理層

tcp/udp屬于運(yùn)送層

TCP服務(wù)提供了數(shù)據(jù)流傳播、可靠性、有效流控制、全雙工操作和多路復(fù)用技術(shù)等。

與TCP不一樣,UDP并不提供對IP協(xié)議的可靠機(jī)制、流控制以及錯(cuò)誤恢復(fù)功能等。由

于UDP比較簡樸,UDP頭包括很少的字節(jié),比TCP負(fù)我消耗少。

tcp:提供穩(wěn)定的I傳播服務(wù),有流量控制,缺陷是包頭大,冗余性不好

udp:不提供穩(wěn)定U勺服務(wù),包頭小,開銷小

30)(void*)ptr和(*(void**))ptrW、J成果與否相似?

其中ptr為同一種指針(void*)ptr和(*(void**))ptr值是相似的

32)intmain()

(

intx=3;

printf("%d”,x);

return1;

)

問函數(shù)既然不會被其他函數(shù)調(diào)用,為何要返回1?

mian中,c原則認(rèn)為。表達(dá)成功,非。表達(dá)錯(cuò)誤。詳細(xì)歐I值是某中詳細(xì)出錯(cuò)信息

33)要對絕對地址0X100000賦值,我們可以用(unsignedint*)0X100000=1234;那么要是想

讓程序跳轉(zhuǎn)到絕對地址是0X100000去執(zhí)行,應(yīng)當(dāng)怎么做?

?((void(*)())0X100000)();

首先要將0X100000強(qiáng)制轉(zhuǎn)換成函數(shù)指針,即:

(void(*)())0X100000

然后再調(diào)用它:

?((void(*)0)0X100000)();

川typedef可以看得更宜觀些:

typedefvoid(*)()voidFuncPtr;

?((voidFuncPtr)OX100000)();

34)已知一種數(shù)組table,用一種宏定義,求出數(shù)據(jù)的元素個(gè)數(shù)

#defineNTBL

//defineNTBL(sizeof(table)/sizeof(table[0]))

35)線程與進(jìn)程日勺區(qū)別和段絡(luò)?線程與否具有相似的堆棧?dll與否有獨(dú)立口勺堆棧?

進(jìn)程是死H勺,只是某些資源的集合,真正的程序執(zhí)行都是線程來完畢H勺,程序啟動H勺時(shí)

候操作系統(tǒng)就幫你創(chuàng)立了一種主線程。

每個(gè)線程育自己的堆棧。DLL中有無獨(dú)立的堆棧?

這個(gè)問題不好回答,或者說這個(gè)問題自身與否有問題。由于DLL中的代碼是被某些線程

所執(zhí)行,只有線程擁有堆棧,假如DLL中的代碼是EXE中的線程所調(diào)用,那么這個(gè)時(shí)候是

不是說這個(gè)DLL沒有自己獨(dú)立的堆棧?假如DLL中的代碼是由DLL自己創(chuàng)立U勺線程所執(zhí)行,

那么是不是說DLL有獨(dú)立P勺堆棧?

以上講的是堆棧,假如對于堆來說,每個(gè)DLL有自己的堆,因此假如是從DLL中動態(tài)分

派的內(nèi)存,最佳是從DLL中刪除,假如你從DLL中分派內(nèi)存,然后在EXE中,或者此外一種

DLL中刪除,很有也許導(dǎo)致程序瓦解。

36)unsignedshortA=10;

printf("~A=%u\n",~A);

charc=128;

printf(uc=%d\nM,c);

輸出多少?并分析過程

第一題,?A=0xfffffff5,int值為-11,但輸出日勺是uint。因此輸出

第二題,c=0X10,輸出口勺是mt,最高位為1,是負(fù)數(shù),因此它的值就是0X00的補(bǔ)碼

就是128,因此輸出一128。

這兩道題都是在考察二進(jìn)制向int或uint轉(zhuǎn)換時(shí)的J最高位處理.

37)分析下面的程序:

voidGetMemory(char**p,intnum)

(

*p=(char*)malloc(num);

)

intmain()

(

char*str=NULL;

GetMemory(&str,100);

strcpy(str,nhello");

free(str);

if(str!=NULL)

(

strcpy(str,"worldv);

)

printf(<<\nstris%sM,str);軟件開發(fā)網(wǎng)

getcharf);

)

問輸出成果是什么?

輸出strisworldo

free只是釋放的Jstr指向的內(nèi)存空間,它自身日勺值還是存在的.因此free之后,有一種好

的習(xí)慣就是將str=NULL.

此時(shí)str指向空間的內(nèi)存已被回收,假如輸出語句之前還存在分派空間的操作的話,這段存儲

空間是也許被重新分派給其他變量口勺,

盡管這段程序確實(shí)是存在大大歐I問題(上面各位已經(jīng)說得很清晰了),不過一般會打印出

world來。

這是由于,進(jìn)程中的內(nèi)存管理一般不是由操作系統(tǒng)完畢的,而是由庫函數(shù)自己完畢的。

當(dāng)你malloc一塊內(nèi)存的時(shí)候,管理庫向操作系統(tǒng)申請一塊空間(也許會比你中詩口勺大

某些),然后在這塊空間中記錄某些管理信息(一般是在你申請的內(nèi)存前面一點(diǎn)),并將可

用內(nèi)存W、J地址返回。不過釋放內(nèi)存的時(shí)候,管理庫一般都不會將內(nèi)存還給操作系統(tǒng),因此你

是可以繼續(xù)訪問這塊地址的。

chara[10],strlen⑶為何等于15?運(yùn)行口勺成果

38)//include“stdio.h"

#includeustring.h"

voidmain()

(

charaa[10];

printf(<<%dM,strlen(aa));

)

sizeof()和初不初始化,沒有關(guān)系;

strlen()和初始化有關(guān)。

39)char(*str)[2O];

char*str[20];

40)longa=0X801010;

a+5=?

0X801010用二進(jìn)制表達(dá)為:“1000000000010000C0010000”,十進(jìn)制的值為8392720,

再加上5就是8392725羅

41)給定構(gòu)造

structA

(

chart:4;

chark:4;

unsignedshorti:8;

unsignedlongm;

);

問sizeof(A)=?

給定構(gòu)造

structA

(

chart:4;4位

chark:4;4位

unsignedshorti:8;8位

unsignedlongm;//偏移2字節(jié)保證4字節(jié)對齊

”〃共8字節(jié)

42)下面的函數(shù)實(shí)目前一種數(shù)上加一種數(shù),有什么錯(cuò)誤?請改正。

intadd_n(intn)

(

staticinti=100;

i+=n;

returni;

)

當(dāng)你第一次蜩用H、J得不到對伊加勺成果,莫非你寫個(gè)困數(shù)就是為了調(diào)用一次?問胭就出在

static上?

43)分析一下

#include

#include

#include

//include

#include

#include

typedefstructAA

(

intbl:5;

intb2:2;

}AA;

voidmain()

(

AAaa;

charcc[100];

MM

strcpy(cczabcdefgnijklmnopqrstuvwxyz);

memcpy(&aa/cc,sizeof(AA));

cout?aa.bl?encl;

cout?aa.b2?encl;

)

答案是-16和1

首先sizeof(AA)H勺大小為4,bl和b2分別占5bit和2bit.通過strcpy和memcpy后,aa的4

個(gè)字節(jié)所寄存H勺值是:0,1,2,3的JASC碼,即00110000,00110001,00110010,00110011因此,

最終一步:顯示的是這4個(gè)字節(jié)U勺前5位,和之后的2位分別為:10000,和01,由于int

是有正負(fù)之分

因此:答案是T6和1

44)求函數(shù)返回值,輸入x=9999;

intfunc(x)

(

intcountx=0;

while(x)

(

countx十十;

x=x&(x-l);

)

returncountx;

)

成果呢?

懂得了這是記錄9999的二進(jìn)制數(shù)值中有多少個(gè)1的函數(shù),且有9999=9X1024+512

+256+15

9X1024中具有1的個(gè)數(shù)為2;

512中具有1的個(gè)數(shù)為1;

256中具有1的個(gè)數(shù)為1;

15中具有1日勺個(gè)數(shù)為4;軟件開發(fā)網(wǎng)

故共有1的個(gè)數(shù)為8,成果為8。

1000?1=0111,恰好是原數(shù)取反。這就是原理。

用這種措施來求1的個(gè)數(shù)是很效率很高的。

不必去一種一種地移位。循環(huán)次數(shù)至少。

請寫函數(shù)實(shí)現(xiàn),不可以變化數(shù)據(jù)類型,如將改為關(guān)鍵是怎樣處理

inta,b,cC=a+bclongint,

溢出問題

booladd(inta,intbjnt*c)

(

*c=a+b;

return(a>0&&b>0&&(*ca11*c>b)));

)

45)分析:

structbit

inta:3;

intb:2;

intc:3;

);

intmain()

(

bits;

char*c=(char*)&s;

cout?sizeof(bit)?endl;

*c=0X99;

cout?s.a<?s.b?endl?s.c?endl;

inta=-l;

printf(<4%xM,a);

return0;

)

輸出為何是

4

1

-1

-4

甘ft甘ft甘ft甘ft

由于0X99在內(nèi)存中表達(dá)為1001(001,a=001,b=11,0=100。當(dāng)c為有符合數(shù)時(shí),c=100,

最高1為表達(dá)c為負(fù)數(shù),負(fù)數(shù)在計(jì)算機(jī)用補(bǔ)碼表達(dá),因此c=-4;同理b=?l;當(dāng)c為有符合數(shù)

時(shí),c=100,即c=4,同理b=3o</sizeof(bit)?endl;

</endl;

</endl;

46)位域:

有些信息在存儲時(shí),并不需要占用一種完整口勺字節(jié),而只需占幾種或一種

二進(jìn)制位。例如在寄存一種開關(guān)量時(shí),只有F和1兩種狀態(tài),用一位二進(jìn)位即

可。為了節(jié)省存儲空間,并使處理簡便,C語言乂提供了一種數(shù)據(jù)構(gòu)造,稱為

“位域”或“位段”。所謂“位域”是把一種字節(jié)中的二進(jìn)位劃分為幾種不一樣

H勺區(qū)域,并闡明每個(gè)區(qū)域H勺位數(shù)。每個(gè)域有一種域名,容許在程序中按域名進(jìn)

行操作。這樣就可以把幾種不一樣的對象用一種字節(jié)日勺二進(jìn)制位域來表達(dá)。一、

位域的定義和位域變量的闡明位域定義與構(gòu)造定義相仿,其形式為:

struct位域構(gòu)造名{位域列表};其中位域列表的形式為:類型闡明符位域

名:位域長度

例如:

structbs

(

inta:8;

intb:2;

intc:6;

};

位域變量的闡明與構(gòu)造變量闡明日勺方式相似??刹捎孟榷x后闡明,同步定

義闡明或者直接闡明這三種方式。例如:

structbs

(

inta:8;

intb:2;

intc:6;

}data;

闡明data為bs變量,共占兩個(gè)字節(jié)。其中位域a占8位,位域b占2位:位

域c占6位。對于位域H勺定義尚有如下幾點(diǎn)闡明:

一種位域必須存儲在同一種字節(jié)中,不能跨兩個(gè)字節(jié)。如一種字節(jié)所剩空間

不夠寄存另一位域時(shí),應(yīng)從下一單元起寄存該位域。也可以故意使某位域從下一

單元開始。例如:

structbs

(

unsigneda:4

unsigned:0

unsignedb:4

unsignedc:4

}

在這個(gè)位域定義中,a占第一字節(jié)的4位,后4位填0表達(dá)不使用,b從第

二字節(jié)開始,占用4位,c占用4位。

由于位域不容許跨兩個(gè)字節(jié),因此位域H勺長度不能不小于一種字節(jié)的長度,

也就是說不能超過8位二進(jìn)位。

位域可以無位域名,這時(shí)它只用來作填充或調(diào)整位置。無名的位域是不能使

用的。例如:

structk

(

inta:1

int:2

intb:3

intc:2

};

從以上分析可以看出,位域在本質(zhì)上就是一種構(gòu)造類型,不過其組員是按

二進(jìn)位分派日勺。

位域的使用位域的使用和構(gòu)導(dǎo)致員的使用相似,其一般形式為:位域變量

名?位域名位域容許用多種格式輸出。

main()

(

structbs

(

unsigneda:1;

unsignedb:3;

unsignedc:4;

}

bit,*pbit;

bit.a=l;

bit.b=7;

bit.c=15;

pri

47)改錯(cuò):

ttinclude

intmain(void)

(

int**p;

intarr[100];

p=&arr;

return0;

)

解答:搞錯(cuò)了,是由針類型不一樣,int**p;〃二級指針&arr;〃得到日勺是

指向第一維為100%I數(shù)組的指針

#include

intmain(void)

(

int**p,*q;

intarr[100];

q=arr;

P=&q;

return0;

)

48)下面這個(gè)程序執(zhí)行后會有什么錯(cuò)誤或者效果:

#defineMAX255

intmain()

(

unsignedcharA[MAX],i;//i被定義為unsignedchar

for(i=O;i<=MAX:i++)

A[i]=i;

return0;

)

解答:死循環(huán)加數(shù)組越界訪問(C/C++不進(jìn)行數(shù)組越界檢查)MAX=255數(shù)組

A日勺下標(biāo)范圍為:0..MAX-1,這是其一..

其二.當(dāng)i循環(huán)到255時(shí),循環(huán)內(nèi)執(zhí)行:A[255]=255;這句自身沒有問題..不過返回

for(i=0;i<=MAX;i++)語句時(shí),由于unsignedchar的|取值范圍在(0..255),i++

后來i又為0了..無限循環(huán)下去。

49)structname1

(

charstr;

shortx;

intnum;

)

structname2

charstr;

intnum;

shortx;

)

sizeof(structnamel)=8,sizeof(structname2)=12

在第二個(gè)構(gòu)造中,為保證num按四個(gè)字節(jié)對齊,char后必須留出3字節(jié)啊

空間;同步為保證整個(gè)構(gòu)造的自然對齊(這里是4字節(jié)對齊),在x后還要補(bǔ)齊

2個(gè)字節(jié),這樣就是12字節(jié)。

50)intel:

A.c和B.c兩個(gè)c文獻(xiàn)中使用了兩個(gè)相似名字的static變量,編譯日勺時(shí)候會

不會有問題?這兩個(gè)static變量會保留到哪里(棧還是堆或者其他的)?

static的全局變量,表明這個(gè)變量僅在本模塊中故意義,不會影響其他模塊。

他們都放在數(shù)據(jù)區(qū),不過編譯器對他們的命名是不一樣的。假如要使變量在其他

模塊也故意義的話,需要使用extern關(guān)鍵字。

51)structsi

(

inti:8;

intj:4;

inta:3;

doubleb;

};

structs2

(

inti:8;

intj:4;

doubleb;

inta:3;

};

printf(Z,sizeof(sl)=%d\n〃,sizeof(si));

printf(z/sizeof(s2)=%d\n,z,sizeof(s2));

result:16,24

第一種structsi

(

inti:8;

intj:4;

inta:3;

doubleb;

};

理論上是這樣的I,首先是i在相對0的位置,占8位一種字節(jié),然后,j就

在相對一種字節(jié)日勺位置,由于一種位置的J字節(jié)數(shù)是4位日勺倍數(shù),因此不用對齊,

就放在那里了,然后是a,要在3位的倍數(shù)關(guān)系的位置上,因此要移一位,在15

位的位置上放下,目前總共是18位,折算過來是2字節(jié)2位的樣子,由于

double是8字節(jié)日勺,因此要在相對0要是8個(gè)字節(jié)的位置上放下,因此從18

位開始到8個(gè)字節(jié)之間H勺位置被忽視,直接放在8字節(jié)的位置了,因此,總共

是16字節(jié)。

第二個(gè)最終會對照是不是構(gòu)造體內(nèi)最大數(shù)據(jù)口勺倍數(shù),不是的話,會補(bǔ)成是

最大數(shù)據(jù)的倍數(shù)。

40.鏈表題:一種鏈表日勺結(jié)點(diǎn)構(gòu)

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論