C和C++的區(qū)別和聯(lián)系(擴(kuò)展知識(shí))

?復(fù)習(xí)整理:C/C++區(qū)別與聯(lián)系念搬;

關(guān)于C和C++的區(qū)別是面試中經(jīng)常會(huì)被問到的問題久信,本著即將面試的心態(tài),進(jìn)行知識(shí)整理角骤,并對(duì)小知識(shí)點(diǎn)進(jìn)行擴(kuò)展;

C/C++的聯(lián)系:

C++是C的超集心剥,兼容大部分C的語法的結(jié)構(gòu)邦尊;

聯(lián)系嘛我只能想到這個(gè),畢竟cplusplus嘛优烧!

C/C++區(qū)別:

第一點(diǎn)就應(yīng)該想到C是面向過程的語言蝉揍,而C++是面向?qū)ο蟮恼Z言,一般簡(jiǎn)歷上第一條都是熟悉C/C++基本語法畦娄,了解C++面向?qū)ο笏枷胗终矗敲幢滓牵?qǐng)問什么是面向?qū)ο螅?/p>

C和C++動(dòng)態(tài)管理內(nèi)存的方法不一樣,C是使用malloc/free函數(shù)杖刷,而C++除此之外還有new/delete關(guān)鍵字励饵;(關(guān)于malooc/free與new/delete的不同又可以說一大堆,最后的擴(kuò)展_1部分列出十大區(qū)別)滑燃;

接下來就不得不談到C中的struct和C++的類役听,C++的類是C所沒有的,但是C中的struct是可以在C++中正常使用的表窘,并且C++對(duì)struct進(jìn)行了進(jìn)一步的擴(kuò)展典予,使struct在C++中可以和class一樣當(dāng)做類使用,而唯一和class不同的地方在于struct的成員默認(rèn)訪問修飾符是public,而class默認(rèn)的是private;

C++支持函數(shù)重載乐严,而C不支持函數(shù)重載瘤袖,而C++支持重載的依仗就在于C++的名字修飾與C不同,例如在C++中函數(shù)int fun(int ,int)經(jīng)過名字修飾之后變?yōu)?_fun_int_int ,而C是

_fun昂验,一般是這樣的捂敌,所以C++才會(huì)支持不同的參數(shù)調(diào)用不同的函數(shù);

C++中有引用凛篙,而C沒有黍匾;這樣就不得不提一下引用和指針的區(qū)別(文后擴(kuò)展_2);

當(dāng)然還有C++全部變量的默認(rèn)鏈接屬性是外鏈接,而C是內(nèi)連接呛梆;

C 中用const修飾的變量不可以用在定義數(shù)組時(shí)的大小,但是C++用const修飾的變量可以(如果不進(jìn)行&,解引用的操作的話磕诊,是存放在符號(hào)表的填物,不開辟內(nèi)存);

當(dāng)然還有局部變量的聲明規(guī)則不同霎终,多態(tài)滞磺,C++特有輸入輸出流之類的,很多莱褒,下面就不再列出來了击困; “`

小知識(shí)點(diǎn)補(bǔ)充擴(kuò)展

C/C++學(xué)習(xí)交流QQ群728483370,大家一起加油广凸!

擴(kuò)展_1: 細(xì)數(shù)malloc/free和new/delete的十點(diǎn)區(qū)別

malloc是從堆上開辟空間阅茶,而new是從自由存儲(chǔ)區(qū)開辟;(自由存儲(chǔ)區(qū)是

C++抽象出來的概念谅海,不僅可以是堆脸哀,還可以是靜態(tài)存儲(chǔ)區(qū));

malloc/free是函數(shù)扭吁,而new/delete是關(guān)鍵字撞蜂;

malloc對(duì)開辟的空間大小需要嚴(yán)格指定盲镶,而new只需要對(duì)象名;

malloc開辟的空間即可以給單個(gè)對(duì)象用也可以給數(shù)組用蝌诡,釋放的方式都是

free()溉贿;而new開辟對(duì)象數(shù)組用的是new[size] ,釋放的的時(shí)候是 delete[]

(盡管內(nèi)置類型可能不會(huì)引起問題,但是自定義類型的話浦旱,delete[]需要知道有

多少個(gè)對(duì)象顽照,而這個(gè)計(jì)數(shù)就被放在這塊空間的頭部);

返回值問題,malloc開辟成功返回void*闽寡,需要強(qiáng)轉(zhuǎn)代兵,失敗返回NULL,new

成功返回對(duì)象指針爷狈,失敗拋出異常(這就可能會(huì)提到C++的new_handler機(jī)

制)植影,雖然為了最大程度的兼容C,C++的new也支持失敗返回NULL涎永,但是一般不

被使用思币,大家可以了解一下;

是否調(diào)用構(gòu)造和析構(gòu)羡微,這點(diǎn)應(yīng)該放在前面谷饿,new和free不但負(fù)責(zé)開辟空間,

還會(huì)調(diào)用對(duì)象的構(gòu)造函數(shù)和析構(gòu)函數(shù)妈倔;最好了解一下new的三種表達(dá)形式(new運(yùn)

算符博投,operator new(); placement new();)還有定位new表達(dá)式的

使用;

是否可以相互調(diào)用盯蝴,new的實(shí)現(xiàn)可以用malloc毅哗,malloc的實(shí)現(xiàn)不可以使用

new;

是否可以被重載捧挺,我們可以重載自己的operator new/delete虑绵,但是不可

以重載new/delete/malloc/free;

malloc開辟 的內(nèi)存如果太小,想要換一塊大一點(diǎn)的闽烙,可以調(diào)用relloc實(shí)

現(xiàn)翅睛,但是new沒有直觀的方法來改變;

第十點(diǎn)其實(shí)前面已經(jīng)提到黑竞,當(dāng)new中的底層實(shí)現(xiàn)如果獲取不到更多的內(nèi)存捕发,

會(huì)觸發(fā)new_handler機(jī)制,留有一個(gè)set_new_handler句柄摊溶,看看用戶是否設(shè)

置了這個(gè)句柄爬骤,如果設(shè)置了就去執(zhí)行,句柄的目的是看看能不能嘗試著從操作系

統(tǒng)釋放點(diǎn)內(nèi)存莫换,找點(diǎn)內(nèi)存霞玄,如果實(shí)在不行就拋出bad_alloc異常骤铃;而malloc就

沒有這種嘗試了;——-

擴(kuò)展_2 指針和引用的區(qū)別

1.指針有自己的一塊空間坷剧,而引用只是一個(gè)別名惰爬;

2.使用sizeof看一個(gè)指針的大小是4,而引用則是被引用對(duì)象的大斜蛊蟆撕瞧;

3.指針可以被初始化為NULL,而引用必須被初始化且必須是一個(gè)已有對(duì)象

的引用狞尔;

4.作為參數(shù)傳遞時(shí)丛版,指針需要被解引用才可以對(duì)對(duì)象進(jìn)行操作,而直接對(duì)引

用的修改都會(huì)改變引用所指向的對(duì)象偏序;

5.可以有const指針页畦,但是沒有const引用;

6.指針在使用中可以指向其它對(duì)象研儒,但是引用只能是一個(gè)對(duì)象的引用豫缨,不能

被改變;

7.指針可以有多級(jí)指針(**p)端朵,而引用至于一級(jí)好芭;

8.指針和引用使用++運(yùn)算符的意義不一樣;

擴(kuò)展_3 常見關(guān)鍵字的作用

**1.static 關(guān)鍵字:**

? ? 修飾全局變量時(shí)冲呢,會(huì)將變量的鏈接屬性變?yōu)閮?nèi)部鏈接屬性舍败,并且變量

? ? 的存儲(chǔ)位置變?yōu)槿朱o態(tài)區(qū);

? ? 修飾 局部變量碗硬,改變局部變量的存儲(chǔ)位置為靜態(tài)存儲(chǔ)區(qū)瓤湘,改變局部變

? ? 量的生命周期為整個(gè)程序開始到結(jié)束;

? ? 修飾類的成員變量和函數(shù):屬于類而不屬于對(duì)象恩尾,屬于所有實(shí)例類;

**2.const關(guān)鍵字**

? ? 修飾全局變量:C/C++略有不同挽懦,在上文已經(jīng)提到翰意,即C++的const修

? ? 飾的全局變量可以作為屬組的初始化的大小,而C不可以信柿;同時(shí)變量的

? ? 值不能被修改冀偶;C++利用const的這一屬性,代替C中的define進(jìn)行

? ? 全局常量的定義渔嚷;擴(kuò)展_4會(huì)就 define进鸠,const,inline進(jìn)行對(duì)比

? ? 和分析形病;

? ? 修飾局部變量:代表局部變量的值不能被修改客年;

? ? 修飾指針:這個(gè)是經(jīng)常問道的霞幅,我舉的例子可能不全面,但是是比較

? ? 常見的例子:

? ? cons t int *p;? //修飾的是p所指向的內(nèi)容不能被改變量瓜,p可

? ? 以司恳;

? ? int const *p;? //和上面是一樣的;

? ? int* const p;? //修飾的p指針不能改變绍傲;

? ? 修飾類的成員變量:必須在初始化列表初始化扔傅,除此之外,必須在初

? ? 始化列表初始化的還有烫饼,引用類型的數(shù)據(jù)成員猎塞,沒有默認(rèn)構(gòu)造函數(shù)的

? ? 對(duì)象成員,如果存在繼承關(guān)系杠纵,如果父類沒有默認(rèn)的構(gòu)造函數(shù)荠耽,則也

? ? 必須在初始化列表中被初始化,初始化列表對(duì)數(shù)據(jù)成員的初始化順序

? ? 是按照數(shù)據(jù)成員的聲明順序嚴(yán)格執(zhí)行的淡诗;

? ? 修飾類的成員函數(shù):一般放在成員函數(shù)的最后面骇塘,修飾的是類的成員

? ? 函數(shù)中的隱藏參數(shù)this指針,代表不可以通過this指針修改類的數(shù)據(jù)

? ? 成員韩容,聲明形式例如:

? ? Base::void fun() const;

? ? 關(guān)于const還有一個(gè)問題就是傳參和賦值的問題款违,一般來說,const

? ? 修飾的變量是安全的群凶,沒有const修飾的變量是不安全的插爹,一般在傳

? ? 參的時(shí)候,非const修飾的的變量可以傳給const修飾的请梢,而const

? ? 修飾的不可以傳給非const修飾的形參赠尾,這就相當(dāng)于把安全的東西交

? ? 給了不安全的人;而賦值的話更不用說了毅弧,const修飾的不可以傳給

? ? 沒有const修飾的變量气嫁;

**3.volatile**

? ? volatile一般修飾變量,而它存在的原因是因?yàn)楣蛔覀兊某绦蛟谶M(jìn)行

? ? 編譯的時(shí)候寸宵,編譯器會(huì)進(jìn)行一系列的優(yōu)化,比如元咙,某個(gè)變量被修飾為

? ? const的梯影,編譯器就認(rèn)為,這個(gè)值是只讀的庶香,就會(huì)在寄存器中保存這

? ? 個(gè)變量的值甲棍,每次需要的時(shí)候從寄存器直接讀取,但是有時(shí)候赶掖,我們

? ? 可能會(huì)在不經(jīng)意間修改了這個(gè)變量感猛,比如說我們?nèi)チ诉@個(gè)變量的地

? ? 址七扰,然后強(qiáng)行改變這個(gè)變量在內(nèi)存中的值,那么編譯器并不知道唱遭,讀

? ? 取還是從寄存器中讀取戳寸,這就造成了結(jié)果的不匹配,而volatile聲明

? ? 的變量就會(huì)告訴編譯器拷泽,這個(gè)變量隨時(shí)會(huì)改變疫鹊,需要每次都從內(nèi)從中

? ? 讀取,就是不需要優(yōu)化司致,從而避免了這個(gè)問題拆吆,其實(shí),volatile應(yīng)用

? ? 更多的場(chǎng)景是多線程對(duì)共享資源的訪問的時(shí)候脂矫,避免編譯器的優(yōu)化枣耀,

? ? 而造成多線程之間的通信不匹配!庭再;


explicit關(guān)鍵字

首先需要了解什么是隱式轉(zhuǎn)換捞奕,即在你沒有進(jìn)行顯示的強(qiáng)轉(zhuǎn)的情況

下,賦值運(yùn)算符左右兩個(gè)類型不一致的對(duì)象進(jìn)行了類型轉(zhuǎn)換拄轻;或者

函數(shù)傳參的時(shí)候進(jìn)行了類型轉(zhuǎn)換颅围; 而explicit關(guān)鍵字存在的目的就是

禁止類的構(gòu)造函數(shù)進(jìn)行隱式的類型轉(zhuǎn)換,常見的就是string類的對(duì)象

就可以隱式類型轉(zhuǎn)換恨搓,比如:

? ? strig? s = "hello world";

? ? 因?yàn)閟tring 有一個(gè)單參的char*構(gòu)造函數(shù)院促,所有可以用hello w

? ? orld構(gòu)造一個(gè)string對(duì)象,然后調(diào)用string 類的拷貝構(gòu)造函數(shù)斧抱;

? ? 有時(shí)候我們并不希望這種不是我們預(yù)期的情況發(fā)生常拓,所以,我們可以

? ? 在類的構(gòu)造函數(shù)之前+explicit關(guān)鍵字辉浦。禁止隱式轉(zhuǎn)換弄抬;

? ? ---希望讀者提建議繼續(xù)補(bǔ)充!(補(bǔ)充文章中講到的所有內(nèi)容的不足之處)


擴(kuò)展_4 define /const/inline 對(duì)比和分析

define作用于程序的預(yù)處理階段宪郊,而預(yù)處理階段做的主要工作為下面幾個(gè)

方面:宏替換眉睹,去注釋以及條件編譯; define起作用的地方就在宏替換階

段废膘,只是單純的將宏替換為代碼,例如:

#define Add(a+b) a+b


下面這段代碼用到了這個(gè)宏:

int main()

? ? {

? ? ? ? int a = 1;? //如果char a = '1';?

? ? ? ? int b = 2;

? ? ? ? cout<<Add(a+b);

? ? /*? 替換為cout<<1+2;? */

? ? ? ? return 0;

? ? }


從上面這個(gè)例子我們可以看出define的缺點(diǎn)很明顯慕蔚,首先丐黄,define只 是單純的代碼替換,不會(huì)進(jìn)行類型的檢查孔飒,再者灌闺,我們上面的宏定義 也很粗糙艰争,嚴(yán)格點(diǎn)應(yīng)該定義為: #define Add(a,b) (a)+(b) C++中一般建議使用const,枚舉定義常量桂对,這樣就會(huì)有類型檢查甩卓; 而宏定義也可以定義出和函數(shù)一樣的功能: #define Swap(type,a,b) {type tmp, tmp = a; a = b; b = tmp;} 其實(shí)就算這樣寫蕉斜,也還是存在上面提到的問題逾柿,并且這樣還不能進(jìn)行調(diào) 試,因?yàn)楹暝陬A(yù)處理階段就替換了宅此;

于是C++中又提供了一個(gè)inline內(nèi)聯(lián)關(guān)鍵字 机错,可以實(shí)現(xiàn)和define相同的

功能,并且支持類型檢查和調(diào)試父腕,一般聲明在函數(shù)的定義的前面弱匪,不過, inline只是對(duì)編譯器的一種建議璧亮,一般如果代碼在3-5行左右萧诫,且沒有復(fù) 雜的邏輯結(jié)構(gòu),例如循環(huán)啊枝嘶,遞歸啊帘饶,就可以聲明為inline,inline也

是在函數(shù)調(diào)用的地方替換代碼塊躬络,所以代碼太長(zhǎng)的話尖奔,容易造成程序膨脹,那么inline為什么可以支持調(diào)試呢穷当?

其實(shí)支持調(diào)試也只是在dbug模式下提茁,inline真正起作用是在release模

式,正好和assert相反馁菜;

提到inline,就不得不提friend友元茴扁;被一個(gè)類中聲明為友元的非本類函數(shù)和類,可以訪問本類的私有成員汪疮,這個(gè)關(guān)鍵字的存在感覺有些破壞類的封

裝性峭火,而且,友元屬性不能被傳遞和繼承智嚷;(但是實(shí)際中在有些編譯器下友元函數(shù)被子類繼承了卖丸,我也很納悶,讀者可以自己驗(yàn)證一下盏道,留言I越)C/C++學(xué)習(xí)交流QQ群728483370,大家一起加油!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末衅枫,一起剝皮案震驚了整個(gè)濱河市嫁艇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弦撩,老刑警劉巖步咪,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異益楼,居然都是意外死亡猾漫,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門偏形,熙熙樓的掌柜王于貴愁眉苦臉地迎上來静袖,“玉大人,你說我怎么就攤上這事俊扭《映龋” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵萨惑,是天一觀的道長(zhǎng)捐康。 經(jīng)常有香客問我,道長(zhǎng)庸蔼,這世上最難降的妖魔是什么解总? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮姐仅,結(jié)果婚禮上花枫,老公的妹妹穿的比我還像新娘。我一直安慰自己掏膏,他們只是感情好劳翰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著馒疹,像睡著了一般佳簸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颖变,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天生均,我揣著相機(jī)與錄音,去河邊找鬼腥刹。 笑死马胧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的衔峰。 我是一名探鬼主播漓雅,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼录别,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了邻吞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤葫男,失蹤者是張志新(化名)和其女友劉穎抱冷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體梢褐,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旺遮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盈咳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耿眉。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鱼响,靈堂內(nèi)的尸體忽然破棺而出鸣剪,到底是詐尸還是另有隱情,我是刑警寧澤丈积,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布筐骇,位于F島的核電站,受9級(jí)特大地震影響江滨,放射性物質(zhì)發(fā)生泄漏铛纬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一唬滑、第九天 我趴在偏房一處隱蔽的房頂上張望闰非。 院中可真熱鬧,春花似錦溯泣、人聲如沸秀鞭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茄螃。三九已至,卻和暖如春连锯,著一層夾襖步出監(jiān)牢的瞬間归苍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工运怖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拼弃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓摇展,卻偏偏與公主長(zhǎng)得像吻氧,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容

  • 幾種語言的特性 匯編程序:將匯編語言源程序翻譯成目標(biāo)程序編譯程序:將高級(jí)語言源程序翻譯成目標(biāo)程序解釋程序:將高級(jí)語...
    囊螢映雪的螢閱讀 2,877評(píng)論 1 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,093評(píng)論 1 32
  • 題目類型 a.C++與C差異(1-18) 1.C和C++中struct有什么區(qū)別? C沒有Protection行為...
    阿面a閱讀 7,648評(píng)論 0 10
  • 重新系統(tǒng)學(xué)習(xí)下C++振惰;但是還是少了好多知識(shí)點(diǎn)歌溉;socket;unix骑晶;stl痛垛;boost等; C++ 教程 | 菜...
    kakukeme閱讀 19,833評(píng)論 0 50
  • 1.在C++ 程序中調(diào)用被C 編譯器編譯后的函數(shù)桶蛔,為什么要加extern “C”匙头? 答:首先,extern是C/C...
    曾令偉閱讀 919評(píng)論 0 4