最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入淺析C語言與C++的區(qū)別與聯系

 更新時間:2021年11月18日 16:23:02   作者:程序媛張小妍  
這篇文章主要為大家介紹了深入的分析了C語言與C++的區(qū)別與聯系,文中通過詳細的示例進行了對比,以便大家更容易的看懂理解,有需要的朋友可以借鑒參考下

C語言雖說經常和C++在一起被大家提起,但可千萬不要以為它們是一種編程語言。我們來介紹C語言和C++中的區(qū)別和聯系。

首先C++和C語言本來就是兩種不同的編程語言,但C++確實是對C語言的擴充和延伸,并且對C語言提供后向兼容的能力。對于有些人說的C++完全就包含了C語言的說法還是有點別扭的。

一、C語言是面向過程語言,而C++是面向對象語言

我們都知道C語言是面向過程語言,而C++是面向對象語言,說C和C++的區(qū)別,也就是在比較面向過程和面向對象的區(qū)別。

1、面向過程和面向對象的區(qū)別

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

面向對象:面向對象編程就是把問題分解成各個對象,建立對象的目的不是為了完成一個步驟,而是為了描述某個事物在整個解決問題的步驟中的行為。

2、面向過程和面向對象的優(yōu)缺點

在學習一些比較抽象的概念時,由于我們的理解能力很有限,有時候一些比較恰當的例子也是有助于我們學習的,因此對二者的優(yōu)缺點比較,還是先舉例子,后總結吧!

(1)用面向過程寫出來的程序就像一份蛋炒飯,也就是米飯和炒的菜均勻的混合在了一起,因此蛋炒飯入味均勻,不會像蓋澆飯那樣,可能有時候吃的菜多飯少,還有時候菜少飯多。但是如果你不喜歡吃蛋炒飯,只想吃肉炒飯,那么原來做的這份蛋炒飯就得倒掉了,重新做一份肉炒飯,廚師就得辛苦了!

(2)用面向對象寫出來的程序就像一份蓋澆飯,也就是米飯和蓋菜分別做好,將蓋菜放在米飯上面,蓋澆飯雖然沒有蛋炒飯那樣入味均勻,但是如果給了你一份土豆絲蓋飯,你又不想吃了,換成牛肉蓋飯,廚師只需要將米飯上面的土豆絲倒掉,重新做一份牛肉放在上面就好了。

那么到底蛋炒飯和蓋澆飯哪個好吃呢?
誰也不能說到底哪個好,畢竟蛋炒飯的餐館和蓋澆飯的餐館都很多,而且生意都很不錯,存在即為合理!
如果非要將二者進行一個高地的比較的話,那就得先設定一個場景了!
蓋澆飯的好處就是”菜”“飯”分離,從而提高了制作蓋澆飯的靈活性。飯不滿意就換飯,菜不滿意換菜。用專業(yè)術語來說就是”可維護性“較好,”飯” 和”菜”的耦合度比較低。
蛋炒飯將”蛋”“飯”攪和在一起,想換”蛋”“飯”中任何一種都很困難,耦合度很高,以至于”可維護性”比較差。

二者的簡單總結如下:

面向過程語言

優(yōu)點:性能比面向對象高,因為類調用時需要實例化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發(fā)、 Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。缺點:沒有面向對象易維護、易復用、易擴展

面向對象語言

優(yōu)點:易維護、易復用、易擴展,由于面向對象有封裝、繼承、多態(tài)性的特性,可以設計出低耦合的系統(tǒng),使系統(tǒng) 更加靈活、更加易于維護缺點:性能比面向過程低

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

1、關鍵字的不同

C語言有32個關鍵字

C++有63個關鍵字

2、后綴名不同

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

3、返回值

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

4、參數列表

在C語言中,函數沒有指定參數列表時,默認可以接收任意多個參數;但在C++中,因為嚴格的參數類型檢測,沒有參數列表的函數,默認為 void,不接收任何參數。

5、缺省參數

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

半缺省參數

void FunTest(int _iParam1, int _iParam2 = 0 )
{}
void FunTest(int _iParam1, int _iParam2 = 0 , int _iParam3/* = 0*/)
{}
void FunTest(int _iParam1, int _iParam2 /* = 0*/,int _iParam3 = 0)
{}

全缺省參數

void FunTest(int _iParam1 = 0, int _iParam = 1)
{ }
 //注意:慎用缺省函數,否則會產生二義性
void FunTest ()
{}
void FunTest (int a = 10 )
{}
//假如使用不帶實參方式調用FunTest()函數時,編譯器將不知道調用哪一個,產生二義性

注意:

  • 在半缺省的情況下,帶缺省值的參數必須放在參數列表的最后面。
  • 缺省參數不能同時在函數的聲明和函數定義中出現,二者只能選其一。
  • 缺省值必須是常量或者全局變量。
  • 缺省參數必須通過值參或常參傳遞。

6、函數重載

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

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

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

  • 靜多態(tài):函數重載,函數模板
  • 動多態(tài)(運行時的多態(tài)):繼承中的多態(tài)(虛函數)。

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

#include <iostream>
using namespace std; 
bool compare(int a,int b)
{
    return a > b;
} 
bool  compare(double a,double b)
{
    return a > b;
} 
int main()
{
    //bool compare(int a,int b);
    compare(10,20);
    compare(10.5,20.5);
    return 0;
}

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

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

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

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

7、const

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

C語言中的const:被修飾后不能做左值,可以不初始化,但是之后沒有機會再初始化。不可以當數組的下標,可以通過指針修改。簡單來說,它和普通變量的區(qū)別只是不能做左值而已。其他地方都是一樣的。

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

比如以下情況:

int b = 20;
const int a = b;

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

const在生成符號時,是local符號。即在本文件中才可見。

如果非要在別的文件中使用它的話,在文件頭部聲明:extern cosnt int data = 10;

這樣生成的符號就是global符號。

總結

C中的const叫只讀變量,只是無法做左值的變量;

C++中的const是真正的常量,但也有可能退化成c語言的常量,默認生成local符號。

8、引用

說到引用,我們第一反應就是想到了他的兄弟:指針。引用從底層來說和指針就是同一個東西,但是在編譯器中它的特性和指針完全不同。

    int a = 10;
	int &b = a;
	int *p = &a;
 
	//b = 20;
	//*p = 20;

首先定義一個變量a = 10,然后我們分別定義一個引用b以及一個指針p指向a。

我們來轉到反匯編看看底層的實現:

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

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

再來看看引用修改:

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

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

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

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

int array[10] = {0};       //定義一個數組

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

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

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

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

將右側的&對左邊的*進行覆蓋:

int (&q)[10] = array;

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

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

int &b = 10;

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

const int &b  = 10;

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

這時因為被const修飾的都會產生一個臨時量來保存這個數據,自然就有地址可取了。

9、malloc,free && new,delete

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

1)、malloc和free是函數,new和delete是運算符。

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

例如:

int *p1 = (int *)malloc(sizeof(int));

int *p2 = new int;     //int *p3 = new int(10);

malloc時需要指定大小,還需要類型轉換。new時不需要指定大小因為它可以從給出的類型判斷,并且還可以同時賦初始值。

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

詳見上一條。

4)、free只釋放空間,delete先調用析構函數再釋放空間(如果需要)。

與第⑤條對應,如果使用了復雜類型,先析構再call operator delete回收內存。

5)、new是先調用構造函數再申請空間(如果需要)。

與第④條對應,我們在調用new的時候(例如int *p2 = new int;這句代碼 ),底層代碼的實現是:首先push 4字節(jié)(int類型的大小),隨后call   operator new函數分配了內存。由于我們這句代碼并未涉及到復雜類型(如類類型),所以也就沒有構造函數的調用。如下是operator new的源代碼,也是new實現的重要函數:

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
        {       // try to allocate size bytes
        void *p;
        while ((p = malloc(size)) == 0)
                if (_callnewh(size) == 0)
                {       // report no memory
                        _THROW_NCEE(_XSTD bad_alloc, );
                }
 
        return (p);
        }

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

6)、內存不足(開辟失敗)時處理方式不同。

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

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

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

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

new就是用malloc()實現的,new是C++獨有malloc當然無法調用。

10、作用域

C語言中作用域只有兩個:局部,全局。

C++中則是有:局部作用域,類作用域,名字空間作用域三種。

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

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

例如我們有一個名字空間叫Myname,其中有一個變量叫做data。

如果我們希望在其他地方使用data的話,需要在文件頭聲明:using Myname::data;

這樣一來data就使用的是Myname中的值了。可是這樣每個符號我們都得聲明豈不是累死?

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

這也就是我們經常看到的using namespace std;的意思啦。

以上就是深入淺析C語言與C++的區(qū)別與聯系的詳細內容,更多關于C語言與C++的區(qū)別聯系的資料請關注腳本之家其它相關文章!

相關文章

  • C語言的數組與指針可以這樣了解

    C語言的數組與指針可以這樣了解

    這篇文章主要介紹了C語言的數組與指針,本文給大家介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C++關于樹的定義全面梳理

    C++關于樹的定義全面梳理

    樹是一種重要的非線性數據結構,直觀地看,它是數據元素(在樹中稱為結點)按分支關系組織起來的結構,很象自然界中的樹那樣。樹結構在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機構都可用樹形象表示,本篇介紹二叉樹的遞歸與非遞歸遍歷的方法
    2022-06-06
  • C語言實現文件內容按行隨機排列的算法示例

    C語言實現文件內容按行隨機排列的算法示例

    這篇文章主要介紹了C語言實現文件內容按行隨機排列的算法,涉及C語言字符串、數組遍歷與隨機數相關算法實現技巧,需要的朋友可以參考下
    2017-09-09
  • C語言中的const和free用法詳解

    C語言中的const和free用法詳解

    C語言中的const和C++中的const是有區(qū)別的,而且在使用VS編譯測試的時候,如果是C的話,請一定要建立一個后綴為C的文件,不要是CPP的文件。因為,兩個編譯器會有差別的。下面通過本文給大家分享C語言中的const和free用法,感興趣的朋友一起看看吧
    2017-04-04
  • C語言實現可保存的動態(tài)通訊錄的示例代碼

    C語言實現可保存的動態(tài)通訊錄的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C語言實現一個簡單的可保存的動態(tài)通訊錄,文中的示例代碼講解詳細,對我們學習C語言有一定幫助,需要的可以參考一下
    2022-07-07
  • C++中4種強制類型轉換的區(qū)別總結

    C++中4種強制類型轉換的區(qū)別總結

    C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用。下面這篇文章主要給大家介紹了C++中4種強制類型轉換的區(qū)別,有需要的朋友們可以參考借鑒,下面來一起看看吧。
    2016-12-12
  • Qt實戰(zhàn)案例之如何利用QProcess類實現啟動進程

    Qt實戰(zhàn)案例之如何利用QProcess類實現啟動進程

    這篇文章主要介紹了Qt實戰(zhàn)案例之如何利用QProcess類實現啟動進程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • c++冒泡排序示例分享

    c++冒泡排序示例分享

    冒泡排序是一種計算機科學領域的較簡單的排序算法,這篇文章主要介紹了c++冒泡排序示例,需要的朋友可以參考下
    2014-03-03
  • 使用Qt框架制作一個表白程序

    使用Qt框架制作一個表白程序

    這篇文章主要為大家詳細介紹了如何使用Qt框架制作一個表白程序,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-01-01
  • C語言二叉樹的概念結構詳解

    C語言二叉樹的概念結構詳解

    二叉樹可以簡單理解為對于一個節(jié)點來說,最多擁有一個上級節(jié)點,同時最多具備左右兩個下級節(jié)點的數據結構。本文將詳細介紹一下C++中二叉樹的實現和遍歷,需要的可以參考一下
    2022-08-08

最新評論

衢州市| 沾化县| 荆州市| 恭城| 富阳市| 岳西县| 肇庆市| 万山特区| 青州市| 岱山县| 新竹市| 大港区| 平昌县| 龙海市| 朔州市| 玛多县| 哈密市| 宁津县| 渑池县| 福建省| 浙江省| 天水市| 大关县| 柘荣县| 定陶县| 碌曲县| 茶陵县| 吴江市| 鹤山市| 富锦市| 德江县| 黔东| 商城县| 闸北区| 汶上县| 台北市| 通榆县| 天长市| 崇阳县| 五华县| 岳阳县|