0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

C語言和C++到底是什么關(guān)系

xCb1_yikoulinux ? 來源:一口Linux ? 作者:一口Linux ? 2022-06-20 11:28 ? 次閱讀

C語言C++到底是什么關(guān)系?

首先C++和C語言本來就是兩種不同的編程語言,但C++確實(shí)是對C語言的擴(kuò)充和延伸,并且對C語言提供后向兼容的能力。對于有些人說的C++完全就包含了C語言的說法也并沒有錯。

C++一開始被本賈尼·斯特勞斯特盧普(Bjarne Stroustrup)發(fā)明時,起初被稱為“C with Classes”,即「帶類的C」。

很明顯它是在C語言的基礎(chǔ)上擴(kuò)充了類class等面向?qū)ο蟮奶匦院蜋C(jī)制。但是后來經(jīng)過一步步修訂和很多次演變,最終才形成了現(xiàn)如今這個支持一系列重大特性的龐大編程語言。

1、C語言是面向過程語言,而C++是面向?qū)ο笳Z言

我們都知道C語言是面向過程語言,而C++是面向?qū)ο笳Z言,說C和C++的區(qū)別,也就是在比較面向過程和面向?qū)ο蟮膮^(qū)別。

(1)面向過程和面向?qū)ο蟮膮^(qū)別

面向過程:面向過程編程就是分析出解決問題的步驟,然后把這些步驟一步一步的實(shí)現(xiàn),使用的時候一個一個的依次調(diào)用就可以了。

面向?qū)ο螅好嫦驅(qū)ο缶幊叹褪前褑栴}分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描述某個事物在整個解決問題的步驟中的行為。

(2)面向過程和面向?qū)ο蟮膬?yōu)缺點(diǎn)

面向過程語言

優(yōu)點(diǎn):性能比面向?qū)ο蟾?,因?yàn)轭愓{(diào)用時需要實(shí)例化,開銷比較大,比較消耗資源;比如單片機(jī)、嵌入式開發(fā)、 Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。

缺點(diǎn):沒有面向?qū)ο笠拙S護(hù)、易復(fù)用、易擴(kuò)展

面向?qū)ο笳Z言

優(yōu)點(diǎn):易維護(hù)、易復(fù)用、易擴(kuò)展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計(jì)出低耦合的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護(hù)

缺點(diǎn):性能比面向過程低。

二、具體語言上的區(qū)別

1、關(guān)鍵字的不同

C語言有32個關(guān)鍵字;

C++有63個關(guān)鍵字;

2、后綴名不同

C源文件后綴.c,C++源文件后綴.cpp,在VS中,如果在創(chuàng)建源文件時什么都不給,默認(rèn)是.cpp。

3、返回值

C語言中,如果一個函數(shù)沒有指定返回值類型,默認(rèn)返回int類型;C++中,如果一個函數(shù)沒有返回值則必須指定為void。

4、參數(shù)列表

在C語言中,函數(shù)沒有指定參數(shù)列表時,默認(rèn)可以接收任意多個參數(shù);但在C++中,因?yàn)閲?yán)格的參數(shù)類型檢測,沒有參數(shù)列表的函數(shù),默認(rèn)為 void,不接收任何參數(shù)。

5、缺省參數(shù)

缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個默認(rèn)值。在調(diào)用該函數(shù)時,如果沒有指定實(shí)參則采用該默認(rèn)值,否則使用指定的參。(C語言不支持缺省參數(shù))

·半缺省參數(shù)

9ac130a0-ef86-11ec-ba43-dac502259ad0.png

·全缺省參數(shù)

9acdc6d0-ef86-11ec-ba43-dac502259ad0.jpg

注意:

·在半缺省的情況下,帶缺省值的參數(shù)必須放在參數(shù)列表的最后面。

·缺省參數(shù)不能同時在函數(shù)的聲明和函數(shù)定義中出現(xiàn),二者只能選其一。

·缺省值必須是常量或者全局變量。

·缺省參數(shù)必須通過值參或常參傳遞。

6、函數(shù)重載

函數(shù)重載:函數(shù)重載是函數(shù)的一種特殊情況,指在同一作用域中,聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形參列表(參數(shù)個數(shù)、類型、順序)必須不同,返回值類型可以相同也可以不同,常用來處理實(shí)現(xiàn)功能類似數(shù)據(jù)類型不同的問題。(C語言沒有函數(shù)重載,C++支持函數(shù)重載)。

C語言中產(chǎn)生函數(shù)符號的規(guī)則是根據(jù)名稱產(chǎn)生,這也就注定了c語言不存在函數(shù)重載的概念。而C++生成函數(shù)符號則考慮了函數(shù)名、參數(shù)個數(shù)、參數(shù)類型。需要注意的是函數(shù)的返回值并不能作為函數(shù)重載的依據(jù),也就是說int sum和double sum這兩個函數(shù)是不能構(gòu)成重載的!

我們的函數(shù)重載也屬于多態(tài)的一種,這就是所謂的靜多態(tài)。

靜多態(tài):函數(shù)重載,函數(shù)模板

動多態(tài)(運(yùn)行時的多態(tài)):繼承中的多態(tài)(虛函數(shù))。

使用重載的時候需要注意作用域問題:請看如下代碼。

9b0b6e72-ef86-11ec-ba43-dac502259ad0.jpg

我在全局作用域定義了兩個函數(shù),它們由于參數(shù)類型不同可以構(gòu)成重載,此時main函數(shù)中調(diào)用則可以正確的調(diào)用到各自的函數(shù)。

但是請看main函數(shù)中被注釋掉的一句代碼。如果將它放出來,則會提出警告:將double類型轉(zhuǎn)換成int類型可能會丟失數(shù)據(jù)。

這就意味著我們編譯器針對下面兩句調(diào)用都調(diào)用了參數(shù)類型int的compare。由此可見,編譯器調(diào)用函數(shù)時優(yōu)先在局部作用域搜索,若搜索成功則全部按照該函數(shù)的標(biāo)準(zhǔn)調(diào)用。若未搜索到才在全局作用域進(jìn)行搜索。

總結(jié):C語言不存在函數(shù)重載,C++根據(jù)函數(shù)名參數(shù)個數(shù)參數(shù)類型判斷重載,屬于靜多態(tài),必須同一作用域下才叫重載。

7、const

C語言中被const修飾的變量不是常量,叫做常變量或者只讀變量,這個常變量是無法當(dāng)作數(shù)組下標(biāo)的。然而在C++中const修飾的變量可以當(dāng)作數(shù)組下標(biāo)使用,成為了真正的常量,這就是C++對const的擴(kuò)展。

C語言中的const:被修飾后不能做左值,可以不初始化,但是之后沒有機(jī)會再初始化。不可以當(dāng)數(shù)組的下標(biāo),可以通過指針修改。

簡單來說,它和普通變量的區(qū)別只是不能做左值而已,其他地方都是一樣的。

C++中的const:真正的常量。定義的時候必須初始化,可以用作數(shù)組的下標(biāo)。const在C++中的編譯規(guī)則是替換(和宏很像),所以它被看作是真正的常量。也可以通過指針修改。需要注意的是,C++的指針有可能退化成C語言的指針。比如以下情況:

9b2a18c2-ef86-11ec-ba43-dac502259ad0.png

這時候的a就只是一個普通的C語言的const常變量了,已經(jīng)無法當(dāng)數(shù)組的下標(biāo)了。(引用了一個編譯階段不確定的值)

const在生成符號時,是local符號。即在本文件中才可見。如果非要在別的文件中使用它的話,在文件頭部聲明:externcosnt int data = 10;這樣生成的符號就是global符號。

總結(jié):C中的const叫只讀變量,只是無法做左值的變量;C++中的const是真正的常量,但也有可能退化成c語言的常量,默認(rèn)生成local符號。

8、引用

說到引用,我們第一反應(yīng)就是想到了他的兄弟:指針。

引用從底層來說和指針就是同一個東西,但是在編譯器中它的特性和指針完全不同。

9b49884c-ef86-11ec-ba43-dac502259ad0.jpg

首先定義一個變量a = 10,然后我們分別定義一個引用b以及一個指針p指向a。我們來轉(zhuǎn)到反匯編看看底層的實(shí)現(xiàn):

9b5fee0c-ef86-11ec-ba43-dac502259ad0.jpg

可以看到底層實(shí)現(xiàn)完全一致,取a的地址放入eax寄存器,再將eax中的值存入引用b/指針p的內(nèi)存中。至此我們可以說(在底層)引用本質(zhì)就是一個指針。

了解了底層實(shí)現(xiàn),我們回到編譯器。我們看到對a的值的修改,指針p的做法是*p = 20;即進(jìn)行解引用后替換值。

再來看看引用修改:

我們看到修改a的值的方法也是一樣的,也是解引用。只是我們在調(diào)用的時候有所不同:調(diào)用p時需要*p解引用,b則直接使用就可以。由此我們 推斷出:引用在直接使用時是指針解引用。p直接使用則是它自己的地址。

這樣我們也了解了,我們給引用開辟的這塊內(nèi)存是根本訪問不到的。如果直接用就直接解引用了。即使打印&b,輸出的也是a的地址。

在此附上將指針轉(zhuǎn)為引用的小技巧:int *p = &a,我們將 引用符號移到左邊 將 *替換即可:int &p = a。

接下來看看如何創(chuàng)建數(shù)組的引用:

intarray[10] = {0};//定義一個數(shù)組

我們知道,array拿出來使用的話就是數(shù)組array的首元素地址。即是int *類型。

那么&array是什么意思呢?int **類型,用來指向array[0]地址的一個地址嗎?不要想當(dāng)然了,&array是整個數(shù)組類型。

那么要定義一個數(shù)組引用,按照上面的小訣竅,先來寫寫數(shù)組指針吧:

int(*q) [10] = &array;

將右側(cè)的&對左邊的*進(jìn)行覆蓋:

int(&q)[10] = array;

測試sizeof(q) = 10。我們成功創(chuàng)建了數(shù)組引用。

經(jīng)過上面的詳解,我們知道了引用其實(shí)就是取地址。那么我們都知道一個立即數(shù)是沒有地址的,即

int&b = 10;

這樣的代碼是無法通過編譯的。那如果你就是非要引用一個立即數(shù),其實(shí)也不是沒有辦法:

constint &b = 10;

即將這個立即數(shù)用const修飾一下,就可以了。為什么呢?

這時因?yàn)楸籧onst修飾的都會產(chǎn)生一個臨時量來保存這個數(shù)據(jù),自然就有地址可取了。

9、malloc,free && new,delete

這個問題很有意思,也是重點(diǎn)需要關(guān)注的問題。malloc()和free()是C語言中動態(tài)申請內(nèi)存和釋放內(nèi)存的標(biāo)準(zhǔn)庫中的函數(shù)。而new和delete是C++運(yùn)算符、關(guān)鍵字。new和delete底層其實(shí)還是調(diào)用了malloc和free。它們之間的區(qū)別有以下幾個方面:

1)、malloc和free是函數(shù),new和delete是運(yùn)算符。

2)、malloc在分配內(nèi)存前需要大小,new不需要。

例如:

int *p1 = (int *)malloc(sizeof(int));int *p2 = new int; //int *p3 = new int(10);

malloc時需要指定大小,還需要類型轉(zhuǎn)換。new時不需要指定大小因?yàn)樗梢詮慕o出的類型判斷,并且還可以同時賦初始值。

3)、malloc不安全,需要手動類型轉(zhuǎn)換,new不需要類型轉(zhuǎn)換。

4)、free只釋放空間,delete先調(diào)用析構(gòu)函數(shù)再釋放空間(如果需要)。

與第⑤條對應(yīng),如果使用了復(fù)雜類型,先析構(gòu)再call operator delete回收內(nèi)存。

5)、new是先調(diào)用構(gòu)造函數(shù)再申請空間(如果需要)。

與第④條對應(yīng),我們在調(diào)用new的時候(例如int *p2 = new int;這句代碼 ),底層代碼的實(shí)現(xiàn)是:首先push 4字節(jié)(int類型的大?。S后call operator new函數(shù)分配了內(nèi)存。由于我們這句代碼并未涉及到復(fù)雜類型(如類類型),所以也就沒有構(gòu)造函數(shù)的調(diào)用。如下是operator new的源代碼,也是new實(shí)現(xiàn)的重要函數(shù):

9ba2619c-ef86-11ec-ba43-dac502259ad0.jpg

我們可以看到,首先malloc(size)申請參數(shù)字節(jié)大小的內(nèi)存,如果失敗(malloc失敗返回0)則進(jìn)入判斷:如果_callnewh(size)也失敗的話,拋出bad_alloc異常。_callnewh()這個函數(shù)是在查看new handler是否可用,如果可用會釋放一部分內(nèi)存再返回到malloc處繼續(xù)申請,如果new handler不可用就會拋出異常。

6)、內(nèi)存不足(開辟失?。r處理方式不同。

malloc失敗返回0,new失敗拋出bad_alloc異常。

7)、new和malloc開辟內(nèi)存的位置不同。

malloc開辟在堆區(qū),new開辟在自由存儲區(qū)域。

8)、new可以調(diào)用malloc(),但malloc不能調(diào)用new。

new就是用malloc()實(shí)現(xiàn)的,new是C++獨(dú)有malloc當(dāng)然無法調(diào)用。

10、作用域

C語言中作用域只有兩個:局部,全局。C++中則是有:局部作用域,類作用域,名字空間作用域三種。

所謂名字空間就是namespace,我們定義一個名字空間就是定義一個新作用域。訪問時需要以如下方式訪問(以std為例)

std::cin<<"123" <<std::endl;

例如我們有一個名字空間叫Myname,其中有一個變量叫做data。如果我們希望在其他地方使用data的話,需要在文件頭聲明:using Myname::data;這樣一來data就使用的是Myname中的值了??墒沁@樣每個符號我們都得聲明豈不是累死?

我們只要using namespace Myname;就可以將其中所有符號導(dǎo)入了。

這也就是我們經(jīng)??吹降膗sing namespace std;的意思啦。

不學(xué)C語言能直接學(xué)C++嗎?

還是像前面所說,C++編程語言的第一大重要組成部分就是「面向過程編程」,而這正是C語言老大哥的領(lǐng)域。即使沒有學(xué)過C語言,一上來就直接學(xué)習(xí)C++的小伙伴,應(yīng)該也難逃『面向過程』這一部分的內(nèi)容。

從理論上來說,學(xué)C++前并不一定非得學(xué)C語言,但是有C語言底子再去學(xué)C++往往更具優(yōu)勢,最起碼「面向過程編程」這一部分內(nèi)容能夠輕車熟路。

原文標(biāo)題:不學(xué)C語言能直接學(xué)C++嗎?

文章出處:【微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7609

    瀏覽量

    137219
  • 編程語言
    +關(guān)注

    關(guān)注

    10

    文章

    1947

    瀏覽量

    34839
  • C++
    C++
    +關(guān)注

    關(guān)注

    22

    文章

    2113

    瀏覽量

    73738

原文標(biāo)題:不學(xué)C語言能直接學(xué)C++嗎?

文章出處:【微信號:yikoulinux,微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    AKI跨語言調(diào)用庫神助攻C/C++代碼遷移至HarmonyOS NEXT

    /C++代碼快速遷移至HarmonyOS NEXT。憑借卓越的兼容性,AKI已成為廠商與開發(fā)者打造鴻蒙原生應(yīng)用過程中廣泛使用的跨語言調(diào)用解決方案。 AKI是一款專為鴻蒙原生開發(fā)設(shè)計(jì)的FFI(外部函數(shù)接口
    發(fā)表于 01-02 17:08

    同樣是函數(shù),在CC++中有什么區(qū)別

    ,即使沒有數(shù)據(jù)返回,也得寫 void。 第二個函數(shù)名。 C語言的函數(shù)名絕對不能重名,除了用上 weak 這樣的黑科技。同一個項(xiàng)目中,函數(shù)重名就會提示重復(fù)定義。 C++因?yàn)楹瘮?shù)重載的存在,函數(shù)名可以相同,只要參數(shù)有區(qū)別就行。這兩個
    的頭像 發(fā)表于 11-29 10:25 ?383次閱讀

    MCU編程語言和開發(fā)環(huán)境介紹

    微控制器單元(Microcontroller Unit,簡稱MCU)是嵌入式系統(tǒng)的核心,廣泛應(yīng)用于各種電子產(chǎn)品中。隨著技術(shù)的發(fā)展,MCU編程語言和開發(fā)環(huán)境也在不斷進(jìn)步,以適應(yīng)不同的應(yīng)用需求。 1.
    的頭像 發(fā)表于 11-01 11:51 ?904次閱讀

    TLV320AIC3254內(nèi)部中的ADC處理模塊和minidsp到底是什么關(guān)系

    我想請問一下幾個問題: 1.3254內(nèi)部中的ADC處理模塊和minidsp到底是什么關(guān)系,是并列的還是串行關(guān)系?還是ADC處理模塊就是minidsp特殊情況下的部分? 2.minidsp的抽取因子該怎么理解,
    發(fā)表于 10-31 06:02

    C語言和C++中結(jié)構(gòu)體的區(qū)別

    同樣是結(jié)構(gòu)體,看看在C語言和C++中有什么區(qū)別?
    的頭像 發(fā)表于 10-30 15:11 ?299次閱讀

    C7000優(yōu)化C/C++編譯器

    電子發(fā)燒友網(wǎng)站提供《C7000優(yōu)化C/C++編譯器.pdf》資料免費(fèi)下載
    發(fā)表于 10-30 09:45 ?0次下載
    <b class='flag-5'>C</b>7000優(yōu)化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>編譯器

    C語言與Java語言的對比

    C語言和Java語言都是當(dāng)前編程領(lǐng)域中的重要成員,它們各自具有獨(dú)特的優(yōu)勢和特點(diǎn),適用于不同的應(yīng)用場景。以下將從語法特性、內(nèi)存管理、跨平臺性、性能、應(yīng)用領(lǐng)域等多個方面對C
    的頭像 發(fā)表于 10-29 17:31 ?385次閱讀

    TMS320LF240x DSP的C語言和匯編代碼快速入門

    電子發(fā)燒友網(wǎng)站提供《TMS320LF240x DSP的C語言和匯編代碼快速入門.pdf》資料免費(fèi)下載
    發(fā)表于 10-18 10:14 ?1次下載
    TMS320LF240x DSP的<b class='flag-5'>C</b><b class='flag-5'>語言和</b>匯編代碼快速入門

    C++語言基礎(chǔ)知識

    電子發(fā)燒友網(wǎng)站提供《C++語言基礎(chǔ)知識.pdf》資料免費(fèi)下載
    發(fā)表于 07-19 10:58 ?7次下載

    PLC編程語言和C語言的區(qū)別

    在工業(yè)自動化和計(jì)算機(jī)編程領(lǐng)域中,PLC(可編程邏輯控制器)編程語言和C語言各自扮演著重要的角色。盡管兩者都是編程語言,但它們在多個方面存在顯著的區(qū)別。本文將從多個維度深入探討PLC編程
    的頭像 發(fā)表于 06-14 17:11 ?3040次閱讀

    為什么很少用C++開發(fā)單片機(jī)

    C語言是面向過程的語言,C++是面向?qū)ο蟮木幊?b class='flag-5'>語言。結(jié)合本文來說,面向過程相比面向?qū)ο蟮木幊蹋纱a量(bin文件)更小,運(yùn)行效率更高。
    發(fā)表于 03-25 14:26 ?1071次閱讀
    為什么很少用<b class='flag-5'>C++</b>開發(fā)單片機(jī)

    plc編程語言c語言的聯(lián)系 c語言和PLC有什么區(qū)別

    語言,主要用于開發(fā)各種應(yīng)用程序。盡管PLC編程語言和C語言有一些相似之處,但它們之間也存在一些明顯的區(qū)別。 首先,PLC編程語言和
    的頭像 發(fā)表于 02-05 14:21 ?4262次閱讀

    c語言,c++,java,python區(qū)別

    C語言C++、Java和Python是四種常見的編程語言,各有優(yōu)點(diǎn)和特點(diǎn)。 C語言
    的頭像 發(fā)表于 02-05 14:11 ?2497次閱讀

    光耦怎么用?光耦的輸入和輸出到底是什么關(guān)系

    光耦怎么用?光耦的輸入和輸出到底是什么關(guān)系? 光耦是一種常見的光電器件,也被稱為光電耦合器。它主要由發(fā)光二極管(LED)和光敏電阻(光電二極管)組成。光耦的輸入端是LED,通過輸入端的電流來控制
    的頭像 發(fā)表于 02-03 17:06 ?3318次閱讀

    vb語言和c++語言的區(qū)別

    VB語言和C++語言是兩種不同的編程語言,雖然它們都屬于高級編程語言,但在設(shè)計(jì)和用途上有很多區(qū)別。下面將詳細(xì)比較VB
    的頭像 發(fā)表于 02-01 10:20 ?2411次閱讀