C++常見基礎(chǔ)知識

1.在C++ 程序中調(diào)用被C 編譯器編譯后的函數(shù),為什么要加extern “C”?

答:首先,extern是C/C++語言中表明函數(shù)和全局變量作用范圍的關(guān)鍵字,該關(guān)鍵字告訴編譯器,其聲明的函數(shù)和變量可以在本模塊或其它模塊中使用。

通常,在模塊的頭文件中對本模塊提供給其它模塊引用的函數(shù)和全局變量以關(guān)鍵字extern聲明。extern "C"是連接申明(linkage declaration),被extern "C"修飾的變量和函數(shù)是按照C語言方式編譯和連接的。作為一種面向?qū)ο蟮恼Z言,C++支持函數(shù)重載,而過程式語言C則不支持。函數(shù)被C++編譯后在符號 庫中的名字與C語言的不同。例如,假設(shè)某個函數(shù)的原型為:void foo( int x, int y );該函數(shù)被C編譯器編譯后在符號庫中的名字為_foo,而C++編譯器則會產(chǎn)生像_foo_int_int之類的名字。這樣的名字包含了函數(shù)名、函數(shù)參 數(shù)數(shù)量及類型信息,C++就是靠這種機制來實現(xiàn)函數(shù)重載的。

所以,可以用一句話概括extern “C”這個聲明的真實目的:解決名字匹配問題,實現(xiàn)C++與C的混合編程。

2.頭文件中的ifndef/define/endif有什么作用?

答:這是C++預(yù)編譯頭文件保護符,保證即使文件被多次包含,頭文件也只定義一次。

3.?#include 與 #include "file.h"的區(qū)別?

答:前者是從標(biāo)準(zhǔn)庫路徑尋找和引用file.h,而后者是從當(dāng)前工作路徑搜尋并引用file.h。

4.評價一下C/C++各自的特點

答:C語言是一種結(jié)構(gòu)化語言,面向過程,基于算法和數(shù)據(jù)結(jié)構(gòu),所考慮的是如何通過一個過程或者函數(shù)從輸入得到輸出;

C++是面向?qū)ο?,基于類、對象和繼承,所考慮的是如何構(gòu)造一個對象模型,讓這個模型能夠契合與之對應(yīng)的問題,通過獲取對象的狀態(tài)信息得到輸出或?qū)崿F(xiàn)過程控制。

5.const 有什么用途?

答:在C/C++中,(1)可以定義const常量,(2)修飾函數(shù)的返回值和形參;

在C++中,還可以修飾函數(shù)的定義體,定義類的const成員函數(shù)。被const修飾的東西受到強制保護,可以預(yù)防意外的變動,提高了程序的健壯性。

6.const和#define有什么區(qū)別?

答:(1)const和#define都可以定義常量,但是const用途更廣。

(2)const 常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對前者進行類型安全檢查。而對后者只進行字符替換,沒有類型安全檢查,并且在字符替換可能會產(chǎn)生意料不到的錯誤。

(3) 有些集成化的調(diào)試工具可以對const 常量進行調(diào)試,但是不能對宏常量進行調(diào)試。

7.關(guān)于sizeof小結(jié)的。

答:sizeof計算的是在棧中分配的內(nèi)存大小。

(1) sizeof不計算static變量占得內(nèi)存;

(2) 指針的大小一定是4個字節(jié),而不管是什么類型的指針;

(3) char型占1個字節(jié),int占4個字節(jié),short int占2個字節(jié)

long int占4個字節(jié),float占4字節(jié),double占48字節(jié),string占4字節(jié)

一個空類占1個字節(jié),單一繼承的空類占1個字節(jié),虛繼承涉及到虛指針?biāo)哉?個字節(jié)

(4) 數(shù)組的長度

若指定了數(shù)組長度,則不看元素個數(shù),總字節(jié)數(shù)=數(shù)組長度*sizeof(元素類型)

若沒有指定長度,則按實際元素個數(shù)類確定

Ps:若是字符數(shù)組,則應(yīng)考慮末尾的空字符。

(5) 結(jié)構(gòu)體對象的長度

在默認情況下,為方便對結(jié)構(gòu)體內(nèi)元素的訪問和管理,當(dāng)結(jié)構(gòu)體內(nèi)元素長度小于處理器位數(shù)的時候,便以結(jié)構(gòu)體內(nèi)最長的數(shù)據(jù)元素的長度為對齊單位,即為其整數(shù)倍。若結(jié)構(gòu)體內(nèi)元素長度大于處理器位數(shù)則以處理器位數(shù)為單位對齊。

(6) unsigned影響的只是最高位的意義,數(shù)據(jù)長度不會改變,所以sizeof(unsigned int)=4

(7) 自定義類型的sizeof取值等于它的類型原型取sizeof

(8) 對函數(shù)使用sizeof,在編譯階段會被函數(shù)的返回值的類型代替

(9) sizeof后如果是類型名則必須加括號,如果是變量名可以不加括號,這是因為sizeof是運算符

(10) 當(dāng)使用結(jié)構(gòu)類型或者變量時,sizeof返回實際的大小。當(dāng)使用靜態(tài)數(shù)組時返回數(shù)組的全部大小,sizeof不能返回動態(tài)數(shù)組或者外部數(shù)組的尺寸

8.sizeof與strlen的區(qū)別?

答: (1)sizeof的返回值類型為size_t(unsigned int);

(2)sizeof是運算符,而strlen是函數(shù);

(3)sizeof可以用類型做參數(shù),其參數(shù)可以是任意類型的或者是變量、函數(shù),而strlen只能用char*做參數(shù),且必須是以’\0’結(jié)尾;

(4)數(shù)組作sizeof的參數(shù)時不會退化為指針,而傳遞給strlen是就退化為指針;

(5)sizeof是編譯時的常量,而strlen要到運行時才會計算出來,且是字符串中字符的個數(shù)而不是內(nèi)存大?。?/p>

9.指針和引用的區(qū)別?

答:指針和引用都提供了間接操作對象的功能。

(1) 指針定義時可以不初始化,而引用在定義時就要初始化,和一個對象綁定,而且一經(jīng)綁定,只要引用存在,就會一直保持和該對象的綁定;

(2) 賦值行為的差異:指針賦值是將指針重新指向另外一個對象,而引用賦值則是修改對象本身;

(3) 指針之間存在類型轉(zhuǎn)換,而引用分const引用和非const應(yīng)用,非const引用只能和同類型的對象綁定,const引用可以綁定到不同但相關(guān)類型的對象或者右值

10.?dāng)?shù)組和指針的區(qū)別?

答:(1)數(shù)組要么在全局?jǐn)?shù)據(jù)區(qū)被創(chuàng)建,要么在棧上被創(chuàng)建;指針可以隨時指向任意類型的內(nèi)存塊;

(2)修改內(nèi)容上的差別:

char a[] = “hello”;

a[0] = ‘X’;

char *p = “world”; // 注意p 指向常量字符串

p[0] = ‘X’; // 編譯器不能發(fā)現(xiàn)該錯誤,運行時錯誤

(3)用運算符sizeof 可以計算出數(shù)組的容量(字節(jié)數(shù))。sizeof(p),p 為指針得到的是一個指針變量的字節(jié)數(shù),而不是p 所指的內(nèi)存容量。C++/C 語言沒有辦法知道指針?biāo)傅膬?nèi)存容量,除非在申請內(nèi)存時記住它。注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進行傳遞時,該數(shù)組自動退化為同類型的指針。

11.空指針和懸垂指針的區(qū)別?

答:空指針是指被賦值為NULL的指針;delete指向動態(tài)分配對象的指針將會產(chǎn)生懸垂指針。

(1) 空指針可以被多次delete,而懸垂指針再次刪除時程序會變得非常不穩(wěn)定;

(2) 使用空指針和懸垂指針都是非法的,而且有可能造成程序崩潰,如果指針是空指針,盡管同樣是崩潰,但和懸垂指針相比是一種可預(yù)料的崩潰。

12.C++中有malloc/free,為什么還有new/delete?

答:malloc/free是C/C++標(biāo)準(zhǔn)庫函數(shù),new/delete是C++運算符。他們都可以用于動態(tài)申請和釋放內(nèi)存。

對于內(nèi)置類型數(shù)據(jù)而言,二者沒有多大區(qū)別。malloc申請內(nèi)存的時候要制定分配內(nèi)存的字節(jié)數(shù),而且不會做初始化;new申請的時候有默認的初始化,同時可以指定初始化;

對于類類型的對象而言,用malloc/free無法滿足要求的。對象在創(chuàng)建的時候要自動執(zhí)行構(gòu)造函數(shù),消亡之前要調(diào)用析構(gòu)函數(shù)。由于malloc /free是庫函數(shù)而不是運算符,不在編譯器控制之內(nèi),不能把執(zhí)行構(gòu)造函數(shù)和析構(gòu)函數(shù)的任務(wù)強加給它,因此,C++還需要new/delete。

13.什么是智能指針?

答:當(dāng)類中有指針成員時,一般有兩種方式來管理指針成員:一是采用值型的方式管理,每個類對象都保留一份指針指向的對象的拷貝;另一種更優(yōu)雅的方式是使用智能指針,從而實現(xiàn)指針指向的對象的共享。

智能指針的一種通用實現(xiàn)技術(shù)是使用引用計數(shù)。智能指針類將一個計數(shù)器與類指向的對象相關(guān)聯(lián),引用計數(shù)跟蹤該類有多少個對象共享同一指針。

每次創(chuàng)建類的新對象時,初始化指針并將引用計數(shù)置為1;當(dāng)對象作為另一對象的副本而創(chuàng)建時,拷貝構(gòu)造函數(shù)拷貝指針并增加與之相應(yīng)的引用計數(shù);對一個對 象進行賦值時,賦值操作符減少左操作數(shù)所指對象的引用計數(shù)(如果引用計數(shù)為減至0,則刪除對象),并增加右操作數(shù)所指對象的引用計數(shù);調(diào)用析構(gòu)函數(shù)時,構(gòu) 造函數(shù)減少引用計數(shù)(如果引用計數(shù)減至0,則刪除基礎(chǔ)對象)。

14.面向?qū)ο蠹夹g(shù)的基本概念是什么,三個基本特征是什么?

答:基本概念:類、對象、繼承; 基本特征:封裝、繼承、多態(tài)。

封裝:將低層次的元素組合起來形成新的、更高實體的技術(shù);

繼承:廣義的繼承有三種實現(xiàn)形式:實現(xiàn)繼承、可視繼承、接口繼承。

多態(tài):允許將子類類型的指針賦值給父類類型的指針

15.C++空類默認有哪些成員函數(shù)?

答:默認構(gòu)造函數(shù)、析構(gòu)函數(shù)、復(fù)制構(gòu)造函數(shù)、賦值函數(shù)

16.哪一種成員變量可以在一個類的實例之間共享?

答:static靜態(tài)成員變量

17.繼承層次中,為什么基類析構(gòu)函數(shù)是虛函數(shù)?

答:編譯器總是根據(jù)類型來調(diào)用類成員函數(shù)。但是一個派生類的指針可以安全地轉(zhuǎn)化為一個基類的指針。這樣刪除一個基類的指針的時候,C++不管這個指針指向 一個基類對象還是一個派生類的對象,調(diào)用的都是基類的析構(gòu)函數(shù)而不是派生類的。如果你依賴于派生類的析構(gòu)函數(shù)的代碼來釋放資源,而沒有重載析構(gòu)函數(shù),那么 會有資源泄漏。

18.為什么構(gòu)造函數(shù)不能為虛函數(shù)?

答:虛函數(shù)采用一種虛調(diào)用的方法。需調(diào)用是一種可以在只有部分信息的情況下工作的機制。如果創(chuàng)建一個對象,則需要知道對象的準(zhǔn)確類型,因此構(gòu)造函數(shù)不能為虛函數(shù)。

19.如果虛函數(shù)是有效的,那為什么不把所有函數(shù)設(shè)為虛函數(shù)?

答:不行。首先,虛函數(shù)是有代價的,由于每個虛函數(shù)的對象都要維護一個虛函數(shù)表,因此在使用虛函數(shù)的時候都會產(chǎn)生一定的系統(tǒng)開銷,這是沒有必要的。

20.構(gòu)造函數(shù)可以是內(nèi)聯(lián)函數(shù)

21.什么是多態(tài)?多態(tài)有什么作用?

答:多態(tài)就是將基類類型的指針或者引用指向派生類型的對象。多態(tài)通過虛函數(shù)機制實現(xiàn)。

多態(tài)的作用是接口重用。

22.重載和覆蓋有什么區(qū)別?

答:虛函數(shù)是基類希望派生類重新定義的函數(shù),派生類重新定義基類虛函數(shù)的做法叫做覆蓋;

重載就在允許在相同作用域中存在多個同名的函數(shù),這些函數(shù)的參數(shù)表不同。重載的概念不屬于面向?qū)ο缶幊?,編譯器根據(jù)函數(shù)不同的形參表對同名函數(shù)的名稱做修飾,然后這些同名函數(shù)就成了不同的函數(shù)。

重載的確定是在編譯時確定,是靜態(tài)的;虛函數(shù)則是在運行時動態(tài)確定。

23.公有繼承、受保護繼承、私有繼承

答:(1)公有繼承時,派生類對象可以訪問基類中的公有成員,派生類的成員函數(shù)可以訪問基類中的公有和受保護成員;

(2)私有繼承時,基類的成員只能被直接派生類的成員訪問,無法再往下繼承;

(3)受保護繼承時,基類的成員也只被直接派生類的成員訪問,無法再往下繼承。

24.公有繼承時基類受保護的成員,可以通過派生類對象訪問但不能修改。

25.有哪幾種情況只能用構(gòu)造函數(shù)初始化列表而不能用賦值初始化?

答:const成員,引用成員

26.什么是虛指針?

答:虛指針或虛函數(shù)指針是虛函數(shù)的實現(xiàn)細節(jié)。帶有虛函數(shù)的每一個對象都有一個虛指針指向該類的虛函數(shù)表。

27.C++如何阻止一個類被實例化?一般在什么時候?qū)?gòu)造函數(shù)聲明為private?

答:(1)將類定義為抽象基類或者將構(gòu)造函數(shù)聲明為private;

(2)不允許類外部創(chuàng)建類對象,只能在類內(nèi)部創(chuàng)建對象

28.main函數(shù)執(zhí)行之前會執(zhí)行什么?執(zhí)行之后還能執(zhí)行代碼嗎?

答:(1)全局對象的構(gòu)造函數(shù)會在main函數(shù)之前執(zhí)行;

(2)可以,可以用_onexit 注冊一個函數(shù),它會在main 之后執(zhí)行;

如果你需要加入一段在main退出后執(zhí)行的代碼,可以使用atexit()函數(shù),注冊一個函數(shù)。

語法:

#include

#include

int atexit(void (*function")(void));

void fn1( void ), fn2( void ), fn3( void );

int main( void )

{

atexit(fn1);

atexit( fn2 );

printf( "This is executed first.\n" );

}

void fn1()

{

printf( " This is\n" );

}

void fn2()

{

printf( " executed next." );

}

結(jié)果:

This is executed first.

This is executed next.

29.請描述進程和線程的區(qū)別?

答:(1)進程是程序的一次執(zhí)行,線程是進程中的執(zhí)行單元;

(2)進程間是獨立的,這表現(xiàn)在內(nèi)存空間、上下文環(huán)境上,線程運行在進程中;

(3)一般來講,進程無法突破進程邊界存取其他進程內(nèi)的存儲空間;而同一進程所產(chǎn)生的線程共享內(nèi)存空間;

(4)同一進程中的兩段代碼不能同時執(zhí)行,除非引入多線程。

30.進程間如何通信?

答:信號、信號量、消息隊列、共享內(nèi)存

31.在網(wǎng)絡(luò)編程中涉及并發(fā)服務(wù)器,使用多進程與多線程的區(qū)別?

答:(1)線程執(zhí)行開銷小,但不利于資源管理和保護;進程則相反,進程可跨越機器遷移。

(2)多進程時每個進程都有自己的內(nèi)存空間,而多線程間共享內(nèi)存空間;

(3)線程產(chǎn)生的速度快,線程間通信快、切換快;

(4)線程的資源利用率比較好;

(5)線程使用公共變量或者資源時需要同步機制。

32.說一下TCP 3次握手、4次揮手的全過程。

33.TCP和UDP有什么區(qū)別。

答:

TCP——傳輸控制協(xié)議,提供的是面向連接、可靠的字節(jié)流服務(wù)。

當(dāng)客戶和服務(wù)器彼此交換數(shù)據(jù)前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數(shù)據(jù)。TCP提供超時重發(fā),丟棄重復(fù)數(shù)據(jù),檢驗數(shù)據(jù),流量控制等功能,保證數(shù)據(jù)能從一端傳到另一端。

UDP——用戶數(shù)據(jù)報協(xié)議,是一個簡單的面向數(shù)據(jù)報的傳輸層協(xié)議。UDP不提供可靠性,它只是把應(yīng)用程序傳給IP層的數(shù)據(jù)報發(fā)送出去,但是并不能保證它們 能到達目的地。由于UDP在傳輸數(shù)據(jù)報前不用在客戶和服務(wù)器之間建立一個連接,且沒有超時重發(fā)等機制,故而傳輸速度很快.

TCP協(xié)議和UDP協(xié)議的一些特性區(qū)別如下:

1.TCP協(xié)議在傳送數(shù)據(jù)段的時候要給段標(biāo)號;UDP 協(xié)議不需要。

2.TCP協(xié)議可靠;UDP協(xié)議不可靠。

3.TCP協(xié)議是面向連接;UDP協(xié)議采用無連接。

4.TCP協(xié)議負載較高,采用虛電路;UDP協(xié)議低負載。

5.TCP協(xié)議的發(fā)送方要確認接受方是否收到數(shù)據(jù)段(3次握手協(xié)議)。

6.TCP協(xié)議采用窗口技術(shù)和流控制。

34.如何編寫套接字?

35.調(diào)用函數(shù)時要進行參數(shù)壓棧,一般情況下順序是從最右邊參數(shù)往左壓棧。

36.經(jīng)常要操作的內(nèi)存分為那幾個類別?

答:(1)棧區(qū):由編譯器自動分配和釋放,存放函數(shù)的參數(shù)值、局部變量的值等;

(2)堆:一般由程序員分配和釋放,存放動態(tài)分配的變量;(new/delete;malloc/free)

(3)全局區(qū)(靜態(tài)區(qū)):全局變量和靜態(tài)變量存放在這一塊,初始化的和未初始化的分開放;

(4)文字常量區(qū):常量字符串就放在這里,程序結(jié)束自動釋放;

(5)程序代碼區(qū):參訪函數(shù)體的二進制代碼。

37.請講述堆和棧的區(qū)別。

答:(1)申請方式不同。棧上有系統(tǒng)自動分配和釋放;堆上有程序員自己申請并指明大??;

(2)棧是向低地址擴展的數(shù)據(jù)結(jié)構(gòu),大小很有限;堆是向高地址擴展,是不連續(xù)的內(nèi)存區(qū)域,空間相對大且靈活;

(3)棧由系統(tǒng)分配和釋放速度快;堆由程序員控制,一般較慢,且容易產(chǎn)生碎片;

38.全局變量放在數(shù)據(jù)段,內(nèi)部變量static int count;放在數(shù)據(jù)段,內(nèi)部變量char *p=“AAA”,p的位置在堆棧上,指向的空間的位置數(shù)據(jù)段,內(nèi)部變量char *p=new char;p的位置堆,指向的空間的位置數(shù)據(jù)段

39.字符數(shù)組與字符串的比較:最明顯的區(qū)別是字符串會在末尾自動添加空字符。

41.類使用static成員的優(yōu)點,如何訪問?

答:優(yōu)點:

(1)static 成員的名字是在類的作用域中,因此可以避免與其他類的成員或全局對象名字沖突;

(2)可以實施封裝。static 成員可以是私有成員,而全局對象不可以;

(3) static 成員是與特定類關(guān)聯(lián)的,可清晰地顯示程序員的意圖。

static 數(shù)據(jù)成員必須在類定義體的外部定義(正好一次),static 關(guān)鍵字只能用于類定義體內(nèi)部的聲明中,定義不能標(biāo)示為static. 不像普通數(shù)據(jù)成員,static成員不是通過類構(gòu)造函數(shù)進行初始化,也不能在類的聲明中初始化,而是應(yīng)該在定義時進行初始化.保證對象正好定義一次的最好 辦法,就是將static 數(shù)據(jù)成員的定義放在包含類非內(nèi)聯(lián)成員函數(shù)定義的文件中。

靜態(tài)數(shù)據(jù)成員初始化的格式為:

<數(shù)據(jù)類型><類名>::<靜態(tài)數(shù)據(jù)成員名>=<值>

類的靜態(tài)數(shù)據(jù)成員有兩種訪問形式:

<類對象名>.<靜態(tài)數(shù)據(jù)成員名> 或 <類類型名>::<靜態(tài)數(shù)據(jù)成員名>

42. static數(shù)據(jù)成員和static成員函數(shù)

答:(1)static數(shù)據(jù)成員:

static數(shù)據(jù)成員獨立于該類的任意對象而存在;每個static數(shù)據(jù)成員是與類關(guān)聯(lián)的對象,并不與該類的對象相關(guān)聯(lián)。Static數(shù)據(jù)成員 (const static數(shù)據(jù)成員除外)必須在類定義體的外部定義。不像普通數(shù)據(jù)成員,static成員不是通過類的構(gòu)造函數(shù)進行初始化,而是應(yīng)該在定義時進行初始 化。

(2)static成員函數(shù):

Static成員函數(shù)沒有this形參,它可以直接訪問所屬類的static成員,不能直接使用非static成員。因為static成員不是任何對象的組成部分,所以static成員不能被聲明為const。同時,static成員函數(shù)也不能被聲明為虛函數(shù)。

43.static成員變量定義放在cpp文件中,不能放在初始化列表中。Const static成員可就地初始化。

44.如何引用一個已經(jīng)定義過的全局變量?

答:可以用引用頭文件的方式,也可以用extern關(guān)鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變量,假定你將那個變量寫錯了,那么在編譯期間會報錯,如果你用extern方式引用時,假定你犯了同樣的錯誤,那么在編譯期間不會報錯,而在連接期間報錯。

44.static關(guān)鍵字的作用。

答:static總是使得變量或?qū)ο蟮拇鎯π问阶兂伸o態(tài)存儲,連接方式變成內(nèi)部連接,對于局部變量(已經(jīng)是內(nèi)部連接了),它僅改變其存儲方式;對于全局變量(已經(jīng)是靜態(tài)存儲了),它僅改變其連接類型。

47.多態(tài)類中的虛函數(shù)表是 Compile-Time,還是 Run-Time時建立的?

答案:虛擬函數(shù)表是在編譯期就建立了,各個虛擬函數(shù)這時被組織成了一個虛擬函數(shù)的入口地址的數(shù)組。而對象的隱藏成員--虛擬函數(shù)表指針是在運行期--也就是構(gòu)造函數(shù)被調(diào)用時進行初始化的,這是實現(xiàn)多態(tài)的關(guān)鍵。

48.?一個父類寫了一個 virtual?函數(shù),如果子類覆蓋它的函數(shù)不加 virtual ,也能實現(xiàn)多態(tài)?

在子類的空間里,有沒有父類的這個函數(shù),或者父類的私有變量? (華為筆試題)

答案:只要基類在定義成員函數(shù)時已經(jīng)聲明了 virtue關(guān)鍵字,在派生類實現(xiàn)的時候覆蓋該函數(shù)時,virtue關(guān)鍵字可加可不加,不影響多態(tài)的實現(xiàn)。子類的空間里有父類的所有變量(static除外)。

49. 完成字符串拷貝可以使用 sprintf、strcpy 及 memcpy 函數(shù),請問這些函數(shù)有什么區(qū)別

,你喜歡使用哪個,為什么?

答案:這些函數(shù)的區(qū)別在于 實現(xiàn)功能以及操作對象不同。

(1)strcpy 函數(shù)操作的對象是字符串,完成從源字符串到目的字符串的拷貝功能。

(2)sprintf 函數(shù)操作的對象不限于字符串:雖然目的對象是字符串,但是源對象可以是字符串、也可以是任意基本類型的數(shù)據(jù)。這個函數(shù)主要用來實現(xiàn)(字符串或基本數(shù)據(jù)類型)向字符串的轉(zhuǎn)換功能。如果源對象是字符串,并且指定 %s 格式符,也可實現(xiàn)字符串拷貝功能。

(3)memcpy 函數(shù)顧名思義就是內(nèi)存拷貝,實現(xiàn)將一個內(nèi)存塊的內(nèi)容復(fù)制到另一個內(nèi)存塊這一功能。內(nèi)存塊由其首地址以及長度確定。程序中出現(xiàn)的實體對象,不論是什么類型, 其最終表現(xiàn)就是在內(nèi)存中占據(jù)一席之地(一個內(nèi)存區(qū)間或塊)。因此,memcpy 的操作對象不局限于某一類數(shù)據(jù)類型,或者說可適用于任意數(shù)據(jù)類型,只要能給出對象的起始地址和內(nèi)存長度信息、并且對象具有可操作性即可。鑒于memcpy 函數(shù)等長拷貝的特點以及數(shù)據(jù)類型代表的物理意義,memcpy 函數(shù)通常限于同種類型數(shù)據(jù)或?qū)ο笾g的拷貝,其中當(dāng)然也包括字符串拷貝以及基本數(shù)據(jù)類型的拷貝。

對于字符串拷貝來說,用上述三個函數(shù)都可以實現(xiàn),但是其實現(xiàn)的效率和使用的方便程度不同:

? strcpy 無疑是最合適的選擇:效率高且調(diào)用方便。

? sprintf 要額外指定格式符并且進行格式轉(zhuǎn)化,麻煩且效率不高。

? memcpy 雖然高效,但是需要額外提供拷貝的內(nèi)存長度這一參數(shù),易錯且使用不便;并且如果長度指定過大的話(最優(yōu)長度是源字符串長度 + 1),還會帶來性能的下降。其實 strcpy 函數(shù)一般是在內(nèi)部調(diào)用 memcpy 函數(shù)或者用匯編直接實現(xiàn)的,以達到高效的目的。因此,使用 memcpy 和 strcpy 拷貝字符串在性能上應(yīng)該沒有什么大的差別。

對于非字符串類型的數(shù)據(jù)的復(fù)制來說,strcpy 和 snprintf 一般就無能為力了,可是對 memcpy 卻沒有什么影響。但是,對于基本數(shù)據(jù)類型來說,盡管可以用 memcpy 進行拷貝,由于有賦值運算符可以方便且高效地進行同種或兼容類型的數(shù)據(jù)之間的拷貝,所以這種情況下 memcpy 幾乎不被使用 。memcpy 的長處是用來實現(xiàn)(通常是內(nèi)部實現(xiàn)居多)對結(jié)構(gòu)或者數(shù)組的拷貝,其目的是或者高效,或者使用方便,甚或兩者兼有。

50. 應(yīng)用程序在運行時的內(nèi)存包括代碼區(qū)和數(shù)據(jù)區(qū),其中數(shù)據(jù)區(qū)又包括哪些部分?

答:對于一個進程的內(nèi)存空間而言,可以在邏輯上分成 3個部份:代碼區(qū),靜態(tài)數(shù)據(jù)區(qū)和動態(tài)數(shù)據(jù)區(qū)。

動態(tài)數(shù)據(jù)區(qū)一般就是“堆棧”。 棧是一種線性結(jié)構(gòu),堆是一種鏈?zhǔn)浇Y(jié)構(gòu)。進程的每個線程都有私有的“棧”。

全局變量和靜態(tài)變量分配在靜態(tài)數(shù)據(jù)區(qū),本地變量分配在動態(tài)數(shù)據(jù)區(qū),即堆棧中。程序通過堆棧的基地址和偏移量來訪問本地變量。

51. C++函數(shù)中值的傳遞方式有哪幾種?

答:三種傳遞方式為:值傳遞、指針傳遞和引用傳遞。

52. C++里面是不是所有的動作都是main()引起的?如果不是,請舉例.

比如全局變量的初始化,就不是由main函數(shù)引起的

舉例: class A{};

A a; //a的構(gòu)造函數(shù)執(zhí)行

int main() {}

54. 內(nèi)聯(lián)函數(shù)在編譯時是否做參數(shù)類型檢查?

答:內(nèi)聯(lián)函數(shù)要做參數(shù)類型檢查, 這是內(nèi)聯(lián)函數(shù)跟宏相比的優(yōu)勢。

55. 全局變量和局部變量有什么區(qū)別?實怎么實現(xiàn)的?操作系統(tǒng)和編譯器是怎么知道的?

(1)生命周期不同:

全局變量隨主程序創(chuàng)建和創(chuàng)建,隨主程序銷毀而銷毀

局部變量在局部函數(shù)內(nèi)部,甚至局部循環(huán)體等內(nèi)部存在,退出就不存在; 內(nèi)存中

分配在全局?jǐn)?shù)據(jù)區(qū)

(2)使用方式不同:通過聲明后全局變量程序的各個部分都可以用到;局部變量只能在局部使用,分配在棧區(qū)

操作系統(tǒng)和編譯器通過內(nèi)存分配的位置來知道的,全局變量分配在全局?jǐn)?shù)據(jù)段并且在程序開始運行的時候被加載。局部變量則分配在堆棧里面 。

57.static全局變量與普通的全局變量有什么區(qū)別?static局部變量和普通局部變量有什么區(qū)別?static函數(shù)與普通函數(shù)有什么區(qū)別?

答:static全局變量與普通全局變量區(qū)別:static全局變量只初使化一次,防止在其他文件單元中被引用;

static局部變量和普通局部變量區(qū)別:static局部變量只被初始化一次,下一次依據(jù)上一次結(jié)果值;

static函數(shù)與普通函數(shù)區(qū)別:static函數(shù)在內(nèi)存中只有一份,普通函數(shù)在每個被調(diào)用中維持一份拷貝。

58.?程序的局部變量存在于(堆棧)中,全局變量存在于(靜態(tài)區(qū)?)中,動態(tài)申請數(shù)據(jù)存在于(?堆)中。

59.?對于一個頻繁使用的短小函數(shù),在C語言中應(yīng)用什么實現(xiàn),在C++中應(yīng)用什么實現(xiàn)?

c用宏定義,c++用inline

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.面向?qū)ο蟮某绦蛟O(shè)計思想是什么? 答:把數(shù)據(jù)結(jié)構(gòu)和對數(shù)據(jù)結(jié)構(gòu)進行操作的方法封裝形成一個個的對象。 2.什么是類?...
    少帥yangjie閱讀 5,129評論 0 14
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out。 檢查...
    SeanC52111閱讀 3,114評論 0 3
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,840評論 18 399
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,691評論 1 51
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,656評論 30 472

友情鏈接更多精彩內(nèi)容