C++面试题一
指針指向一塊內(nèi)存,它的內(nèi)容是指向內(nèi)存的地址;引用是某內(nèi)存的別名
引用使用是無(wú)需解引用,指針需解引用
引用不能為空,指針可以為空
引用在定義是被初始化一次,之后不可變;指針可變
程序?yàn)橹羔樧兞糠峙鋬?nèi)存區(qū)域,而引用不需要分配內(nèi)存區(qū)域
memcpy用來(lái)內(nèi)存拷貝的,它有指定的拷貝數(shù)據(jù)長(zhǎng)度,他可以拷貝任何數(shù)據(jù)類型的對(duì)象
Strcpy它只能去拷貝字符串,它遇到’\0′結(jié)束拷貝
malloc與free是C++/C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)函數(shù),new/delete是C++的運(yùn)算符。它們都可用于申請(qǐng)動(dòng)態(tài)內(nèi)存和釋放內(nèi)存。
對(duì)于非內(nèi)部數(shù)據(jù)類型的對(duì)象而言,光用maloc/free無(wú)法滿足動(dòng)態(tài)對(duì)象的要求。對(duì)象在創(chuàng)建的同時(shí)要自動(dòng)執(zhí)行構(gòu)造函數(shù),對(duì)象在消亡之前要自動(dòng)執(zhí)行析構(gòu)函數(shù)。由于malloc/free是庫(kù)函數(shù)而不是運(yùn)算符,不在編譯器控制權(quán)限之內(nèi),不能夠把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強(qiáng)加于malloc/free。
因此C++語(yǔ)言需要一個(gè)能完成動(dòng)態(tài)內(nèi)存分配和初始化工作的運(yùn)算符new,以及一個(gè)能完成清理與釋放內(nèi)存工作的運(yùn)算符delete。注意new/delete不是庫(kù)函數(shù)。
1.成員變量
結(jié)構(gòu)在默認(rèn)情況下的成員是公共(public)的,
而類在默認(rèn)情況下的成員是私有(private)的。
2.存儲(chǔ)
struct保證成員按照聲明順序在內(nèi)存中存儲(chǔ)。class不保證等等
3.繼承
struct A { };
class B : A{ }; //private繼承
struct C : B{ }; //public繼承
這是由于class默認(rèn)是private,struct默認(rèn)是public。
1.一個(gè)union類型的變量,所有成員變量共享一塊內(nèi)存,該內(nèi)存的大小有這些成員變量中長(zhǎng)度最大的一個(gè)來(lái)決定,struct中成員變量?jī)?nèi)存都是獨(dú)立的
2.union分配的內(nèi)存是連續(xù)的,而struct不能保證分配的內(nèi)存是連續(xù)的
隊(duì)列先進(jìn)先出,棧后進(jìn)先出
16位機(jī)????????2字節(jié)
32位機(jī)????????4字節(jié)
64位機(jī)????????8字節(jié)
extern
可以用引用頭文件的方式,也可以用extern關(guān)鍵字,如果用引用頭文件方式來(lái)引用某個(gè)在頭文件中聲明的全局變理,假定你將那個(gè)變寫(xiě)錯(cuò)了,那么在編譯期間會(huì)報(bào)錯(cuò),如果你用extern方式引用時(shí),假定你犯了同樣的錯(cuò)誤,那么在編譯期間不會(huì)報(bào)錯(cuò),而在連接期間報(bào)錯(cuò)
可以,在不同的C文件中以static形式來(lái)聲明同名全局變量。
可以在不同的C文件中聲明同名的全局變量,前提是其中只能有一個(gè)C文件中對(duì)此變量賦初值,此時(shí)連接不會(huì)出錯(cuò)
for( ;1 ;)和while(1)相同。
前一個(gè)循環(huán)一遍再判斷,后一個(gè)判斷以后再循環(huán)
#include<stdio.h>
main()
{
int a,b,c,d;
a=10;
b=a++;
c=++a;
d=10*a++;
printf(“b,c,d:%d,%d,%d”,b,c,d);
return 0;
}
10,12,120
c用宏定義,c++用inline
全局對(duì)象的構(gòu)造函數(shù)會(huì)在main 函數(shù)之前執(zhí)行。
可以,可以用on_exit 注冊(cè)一個(gè)函數(shù),它會(huì)在main 之后執(zhí)行int fn1(void), fn2(void), fn3(void), fn4 (void);
void main( void )
{
String str(“zhanglin”);
on_exit( fn1 );
on_exit( fn2 );
on_exit( fn3 );
on_exit( fn4 );
printf( “This is executed first.\n” );
}
int fn1()
{
printf( “next.\n” );
return 0;
}
int fn2()
{
printf( “executed ” );
return 0;
}
int fn3()
{
printf( “is ” );
return 0;
}
int fn4()
{
printf( “This ” );
return 0;
}
The on_exit function is passed the address of a function (func) to be called when the program terminates normally. Successive calls to on_exit create a register of functions that are executed in LIFO (last-in-first-out) order. The functions passed to on_exit cannot take parameters.
This is executed next.
能,局部會(huì)屏蔽全局。要用全局變量,需要使用”::”
局部變量可以與全局變量同名,在函數(shù)內(nèi)引用這個(gè)變量時(shí),會(huì)用到同名的局部變量,而不會(huì)用到全局變量。對(duì)于有些編譯器而言,在同一個(gè)函數(shù)內(nèi)可以定義多個(gè)同名的局部變量,比如在兩個(gè)循環(huán)體內(nèi)都定義一個(gè)同名的局部變量,而那個(gè)局部變量的作用域就在那個(gè)循環(huán)體內(nèi)
1.從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static 變量。
2. 在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集。
3. 從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc 或new 申請(qǐng)任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free 或delete 釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但問(wèn)題也最多。
1.成員函數(shù)被重載的特征:
(1)相同的范圍(在同一個(gè)類中);
(2)函數(shù)名字相同;
(3)參數(shù)不同;
(4)virtual 關(guān)鍵字可有可無(wú)。
2.覆蓋是指派生類函數(shù)覆蓋基類函數(shù),特征是:
(1)不同的范圍(分別位于派生類與基類);
(2)函數(shù)名字相同;
(3)參數(shù)相同;
(4)基類函數(shù)必須有virtual 關(guān)鍵字。
3.”隱藏”是指派生類的函數(shù)屏蔽了與其同名的基類函數(shù),規(guī)則如下:
(1)如果派生類的函數(shù)與基類的函數(shù)同名,但是參數(shù)不同。此時(shí),不論有無(wú)virtual關(guān)鍵字,基類的函數(shù)將被隱藏(注意別與重載混淆)。
(2)如果派生類的函數(shù)與基類的函數(shù)同名,并且參數(shù)也相同,但是基類函數(shù)沒(méi)有virtual 關(guān)鍵字。此時(shí),基類的函數(shù)被隱藏(注意別與覆蓋混淆)
1.限制變量的作用域
2.設(shè)置變量的存儲(chǔ)域
1.const 常量有數(shù)據(jù)類型,而宏常量沒(méi)有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒(méi)有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤。
2.有些集成化的調(diào)試工具可以對(duì)const 常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。
堆棧溢出一般是由什么原因?qū)е碌?#xff1f;
沒(méi)有回收垃圾資源
?
數(shù)組要么在靜態(tài)存儲(chǔ)區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧上被創(chuàng)建。指針可以隨時(shí)指向任意類型的內(nèi)存塊。
(1)修改內(nèi)容上的差別
char a[] = “hello”;
a[0] = ‘X’;
char *p = “world”; // 注意p 指向常量字符串
p[0] = ‘X’; // 編譯器不能發(fā)現(xiàn)該錯(cuò)誤,運(yùn)行時(shí)錯(cuò)誤
(2) 用運(yùn)算符sizeof 可以計(jì)算出數(shù)組的容量(字節(jié)數(shù))。sizeof(p),p 為指針得到的是一個(gè)指針變量的字節(jié)數(shù),而不是p 所指的內(nèi)存容量。C++/C 語(yǔ)言沒(méi)有辦法知道指針?biāo)傅膬?nèi)存容量,除非在申請(qǐng)內(nèi)存時(shí)記住它。注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí),該數(shù)組自動(dòng)退化為同類型的指針。
char a[] = “hello world”;
char *p = a;
cout<< sizeof(a) << endl; // 12 字節(jié)
cout<< sizeof(p) << endl; // 4 字節(jié)
計(jì)算數(shù)組和指針的內(nèi)存容量
void Func(char a[100])
{
cout<< sizeof(a) << endl; // 4 字節(jié)而不是100 字節(jié)
}
( ( a + b ) + abs( a – b ) ) / 2
O(n^2)
構(gòu)造函數(shù)(Constructor)
全局變量????????????????????全局靜態(tài)區(qū)
全局靜態(tài)變量????????????????全局靜態(tài)區(qū)
全局常量
????????有初始化????????????代碼區(qū)
????????無(wú)初始化????????????全局靜態(tài)區(qū)
局部變量????????????????????堆棧區(qū)
局部靜態(tài)變量????????????????靜態(tài)區(qū)
局部常量????????????????????堆棧區(qū)
????new和malloc分配空間????堆區(qū)
管道(有名管道,無(wú)名管道),共享內(nèi)存,消息隊(duì)列,信號(hào)量,socket通信
臨界區(qū):通過(guò)對(duì)多線程的串行化來(lái)訪問(wèn)公共資源或一段代碼,速度快,適合控制數(shù)據(jù)訪問(wèn)
互斥量:為協(xié)調(diào)共同對(duì)一個(gè)共享資源的單獨(dú)訪問(wèn)而設(shè)計(jì)
信號(hào)量(PV操作):為控制一個(gè)具有有限數(shù)量用戶資源而設(shè)計(jì)
事件:用來(lái)通知線程有一些事件已
資源:進(jìn)程是擁有資源的一個(gè)獨(dú)立單位,線程是不擁有資源。
調(diào)度:線程作為調(diào)度和分配的基本單位,進(jìn)程是作為資源的基本單位
并發(fā)性:進(jìn)程之間可以有并發(fā)性進(jìn)行,同一個(gè)進(jìn)程中的多個(gè)線程是可以并發(fā)執(zhí)行
系統(tǒng)開(kāi)銷:進(jìn)程在創(chuàng)建和撤銷的時(shí)候,由于系統(tǒng)要分配和回收資源,導(dǎo)致系統(tǒng)的開(kāi)銷明顯大于線程
一個(gè)進(jìn)程可以擁有多個(gè)線程。
能,局部屏蔽全局。在C++里使用全局,需要使用”::”。在C語(yǔ)言里,extern
虛函數(shù)必須實(shí)現(xiàn),純虛函數(shù)沒(méi)有實(shí)現(xiàn)
虛函數(shù)在子類里可以不重載,但是純虛函數(shù)必須在每一個(gè)子類里去實(shí)現(xiàn)
在動(dòng)態(tài)內(nèi)存分配的時(shí)候,析構(gòu)函數(shù)必須是虛函數(shù),但沒(méi)有必要是純虛函數(shù)
封裝、繼承、多態(tài)(抽象)
封裝:把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏
繼承:子類可以擁有父類的屬性和方法,但父類沒(méi)有子類的屬性和方法
多態(tài):允許將子類類型的指針賦值給父類類型的指針
實(shí)現(xiàn)多態(tài),有二種方式,覆蓋,重載
覆蓋,是指子類重新定義父類的虛函數(shù)的做法
重載,是指允許存在多個(gè)同名函數(shù),而這些函數(shù)的參數(shù)表不同(或許參數(shù)個(gè)數(shù)不同,或許參數(shù)類型不同,或許兩者都不同)
vi +5000 filename
2個(gè)字節(jié)
兩個(gè)指針指向鏈表頭,一個(gè)指針每次走一步,另一個(gè)指針每次走兩步,若有一個(gè)指針先指向?yàn)镹ULL表示這個(gè)鏈表無(wú)環(huán)。若兩個(gè)指針重合表示鏈表有環(huán)
換行刷新緩沖區(qū)
printf(“\n”);
使用函數(shù)刷新緩沖區(qū)
fflush(stdout);
程序結(jié)束刷新緩沖區(qū)
return 0;
對(duì)象就是對(duì)客觀事物在計(jì)算機(jī)中的抽象描述。
類就是對(duì)具體相似屬性和行為的一組對(duì)象的統(tǒng)一描述。
類的包括:類說(shuō)明和類實(shí)現(xiàn)兩大部分:
類說(shuō)明提供了對(duì)該類所有數(shù)據(jù)成員和成員函數(shù)的描述。
類實(shí)現(xiàn)提供了所有成員函數(shù)的實(shí)現(xiàn)代碼。
第一范式:沒(méi)有重復(fù)的列
第二范式:非主屬的部分依賴于主屬部分
第三范式:屬性部分不依賴于其他非主屬部分
是在調(diào)試程序使用的一個(gè)宏,括號(hào)里面要滿足,如果不滿足,程序?qū)?bào)告錯(cuò)誤,并將終止執(zhí)行。
用內(nèi)存映射或全局原子(互斥變量)、查找窗口句柄
FindWindow,互斥,寫(xiě)標(biāo)志到文件或注冊(cè)表,共享內(nèi)存
鍵盤(pán)鉤子SetWindowsHookEx
總結(jié)
- 上一篇: Undo/Redo框架实现
- 下一篇: 开发者都应该使用的10个C++11特性