溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C/C++區(qū)別是什么

發(fā)布時間:2020-09-09 11:16:20 來源:億速云 閱讀:154 作者:小新 欄目:編程語言

C/C++區(qū)別是什么?這個問題可能是我們?nèi)粘W習或工作經(jīng)常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!

  C/C++應該從關(guān)鍵字的個數(shù)、源文件、變量定義或聲明位置、函數(shù)、缺省參數(shù)幾個方面進行比較,如果你總是搞混,看了這篇文章會幫助到你。

C/C++從以下幾個方面的比較:

  1. 關(guān)鍵字的個數(shù):
    C語言:C99版本,32個關(guān)鍵字
    C++:C98版本,63個關(guān)鍵字

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

  3. 變量定義或聲明位置:
    C語言必須在第一行定義;C++不做要求

  4. 函數(shù):
    (1)返回值
    C語言中,如果一個函數(shù)沒有指定返回值類型,默認返回int型;
    C++中,對于函數(shù)返回值的檢測更加嚴格,如果一個函數(shù)沒有返回值,則必須指定為void.
    (2)參數(shù)列表
    C語言中,如果函數(shù)沒有指定參數(shù)列表時,默認可以接受任意多個參數(shù);但在C++中,因為嚴格的參數(shù)類型檢測,沒有參數(shù)列表的函數(shù),默認為void,不接受任何參數(shù)。

  5. 缺省參數(shù):
    缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個默認值。在調(diào)用該函數(shù)時,如果沒有指定實參則采用該默認值,否則,使用指定的實參。

//1.實現(xiàn)缺省參數(shù)void Test(int a = 50){
    cout << a << endl;
}
int main(){    Test();    // 輸出50
    Test(100); // 輸出100}

(1)全缺省參數(shù):將所有參數(shù)的缺省值全部給出//代碼

// 實現(xiàn)全缺省參數(shù)void Test(int a = 1,int b = 2,int c = 3)
{    cout << a << "" <<" "<< b << "" <<" "<< c << endl; 
}int main()
{
    Test();//1 2 3
    Test(100);//100 2 3
    Test(100, 200);//100 200 3
    Test(100, 200, 300);//100 200 300}

(2)半缺省參數(shù):規(guī)定,缺省值只能從右往左傳//代碼

// 實現(xiàn)半缺省參數(shù)   注:缺省值只能從右往左傳void Test1(int a = 1, int b = 2, int c = 3)
{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test2(int a , int b = 2, int c = 3)
{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test3(int a , int b , int c = 3)
{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test4(int a = 1, int b , int c = 3)//不能通過編譯,因為它違背了缺省值只能從右往左依次來給這一規(guī)定{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test5(int a = 1, int b = 2, int c )//不能通過編譯,因為它違背了缺省值只能從右往左依次來給這一規(guī)定{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test6(int a = 1, int b , int c )//不能通過編譯,因為它違背了缺省值只能從右往左依次來給這一規(guī)定{    cout << a << "" << " " << b << "" << " " << c << endl;
}void Test7(int a , int b = 2, int c )//不能通過編譯,因為它違背了缺省值只能從右往左依次來給這一規(guī)定{    cout << a << "" << " " << b << "" << " " << c << endl;
}int main()
{
    Test1();//1 2 3}

注意:

a. 帶缺省值的參數(shù)必須放在參數(shù)列表的最后面。
b. 缺省參數(shù)不能同時在函數(shù)聲明和定義中出現(xiàn),只能二者則其一,最好放在函數(shù)聲明中。
c. 缺省值必須是常量或全局變量。

C語言不支持缺省參數(shù)

函數(shù)重載
  • 函數(shù)重載指在同一作用域中聲明幾個功能類似的同名函數(shù),這些同名函數(shù)的形參列表(個數(shù)、類型、類型的次序)必須不同。

//函數(shù)重載void Add();void Add(int a);//行參個數(shù)不一樣void Add(char b);//行參類型不同void Add(int a, char b);void Add(char a, int b);//行參類型的次序不同
  • 僅僅返回值的類型不同,是不能構(gòu)成函數(shù)重載的。

//僅僅返回值的類型不同,是不能構(gòu)成函數(shù)重載的void Add(int a, int b)
{}int Add(int a, int b)
{    return a + b;
}int main()
{
    Add(1, 2);//因為這樣會造成調(diào)用不明確,兩函數(shù)都可以被調(diào)用
    return 0;
}
  • C++支持函數(shù)重載的原因:VS編輯器在底層將函數(shù)參數(shù)的類型編譯到函數(shù)的名字中,因此原函數(shù)名就被換成了另外一個獨一無二的名字。

int Add(int a, int b);    // ?Add@@YAHHH@Zchar Add(int a, int b);   // ?Add@@YADHH@Zchar Add(char a, char b); // ?Add@@YADDD@Z
  • C語言不支持函數(shù)重載的原因:所生成的新的函數(shù)名還是相同的。只是在函數(shù)名前加了_

  • C++中將函數(shù)按C語言風格編譯,只需在函數(shù)前加 extern “c”

extern "C" int Add(char a, int b);
引用

C語言中函數(shù)有兩種傳參方式:傳值傳址

傳值:在函數(shù)調(diào)用過程中會生成一份臨時變量用形參代替,最終把實參的值傳遞給新分配的臨時變量即形參。
傳值優(yōu)點:函數(shù)的副作用不會影響到外部實參。
傳值缺點:不能通過修改參數(shù)來改變外部實參。

傳指:在函數(shù)調(diào)用過程中會生成一份臨時變量用形參代替,最終把實參的地址傳遞給新分配的臨時變量。
傳指優(yōu)點:節(jié)省空間,效率高,改變參數(shù)可以改變外部實參。
傳指缺點:指針不安全,函數(shù)的副作用會影響外部實參。

C++中

引用:
(1)概念:引用不是新定義一個變量,而是給已存在變量取了一個別名,編譯器不會為引用變量開辟內(nèi)存空間,它和它的引用變量共用同一塊內(nèi)存空間。
(2)形式:類型& 引用變量名=引用實體

//引用int main()
{    int a = 10;    int& ra = a;    printf("%p\n", a);    printf("%p\n", ra);//ra和a的地址相同,說明ra和a是同一個實體,他們共用同一塊內(nèi)存空間

    ra = 3;    printf("%d\n", a);//3
    return 0;
}

注:

   a. 引用在定義時,必須初始化。
   b. 一個變量可以被多次引用。
   c. 引用一旦引用了一個實體,就不能在引用其他實體。
   d. 引用變量的生命周期比實體的生命周期短。

(3)常引用

常引用int main()
{    const int a = 1;    //int& ra = a;//編譯會出錯,因為實體a是常量
    const int& ra = a;    double b = 12.34;    //int& rb = b;//編譯會出錯,因為類型不同
    const int& rb = b;    printf("rb=%d\n", rb);//rb=12
    b = 5.0;    printf("b=%f\n", b);//b=5.0
    printf("rb=%d\n", rb);//rb=12
    //b的值改變,但rb的值并沒有隨之改變,說明rb和b是兩個不同的實體}

(4)數(shù)組引用

//數(shù)組引用int a[10];//數(shù)組a的類型為 int[10]int(&ra)[10] = a;

(5)引用場景:
   a.用引用作為函數(shù)的參數(shù)來改變實參。

void Swap(int* pLeft, int* pRight)
{    int temp = *pLeft;    *pLeft = *pRight;    *pRight = temp;
}

void Swap(int& left, int& right)
{    int temp = left;
    left = right;
    right = temp;
}
//如果用引用時不想改變實參的值,則給引用前加const
void Swap(const int& left, const int& right);int main()
{    int a = 10;    int b = 20;
    Swap(&a, &b);//通過傳地址來改變實參    printf(" a=%d ", a);    printf(" b=%d\n", b);

    Swap(a, b);//通過引用來改變實參    printf(" a=%d ", a);    printf(" b=%d\n", b);
}

b.用引用變量作為函數(shù)的返回值    //代碼

情形1:int& FunTest()
{    int a = 10;    return a;
}int main()
{    int b = FunTest();//將函數(shù)的返回值賦給了b
    printf("b=%d\n", b);//b=10
    printf("b=%d\n", b);//b=10
    printf("b=%d\n", b);//b=10
    return 0;
}

情形2:int& FunTest2()
{    int a = 10;    return a;
}int main()
{    int& b=FunTest2();//將函數(shù)的返回值作為實體,
    printf("b=%d\n", b);//b=10
    printf("b=%d\n", b);//隨機值
    printf("b=%d\n", b);//隨機值
    return 0;
}

情形3:int& FunTest3(int& a)
{
    a = 10;    return a;
}int main()
{    int b;    int& rb = FunTest3(b);    printf("b=%d\n", b);//b=10
    printf("rb=%d\n", rb);//rb=10
    printf("rb=%d\n", rb);//rb=10
    printf("rb=%d\n", rb);//rb=10
    return 0;
}
注意:不能返回??臻g上的引用
傳值、傳指、引用 效率比較
//比較struct BigType
{    int array[10000];
};void FunTest(BigType bt)//傳值或傳址{}void FunTest(BigType& bt)//引用{}void TestFunTestRumTime()
{
    BigType bt;
    size_t Start = GetTickCount();    for (i = 0; i < 1000000; i++)
    {
        FunTest(bt);//傳值或傳引用
        FunTest(&bt);//傳址
    }
    size_t End = GetTickCount();    printf("%d\n", End - Start);
}//此代碼檢測出傳值最慢,而傳址和引用速度快且用時差不多相同

引用和指針有什么區(qū)別?

相同點:

  • 列表內(nèi)容

  • 底層的處理方式相同,都是按照指針的方式實現(xiàn)的。

  • 引用變量在底層所對應指針的類型:

  • 引用變量實體的類型* const

不同點:

  • 引用必須要進行初始化;指針不作要求。

  • 普通類型的指針可以在任何時候指向任何一個同類型對象;而引用一旦引用一個實體,就不能再引用其他實體。

  • 指針++:指向下一個地址; 引用++:給數(shù)值++。

  • 在sizeof中含義不同:引用結(jié)果為引用類型的大小;而指針始終是 地址*空間所占字節(jié)個數(shù)。

  • 指針需要手動尋址;而引用通過編譯器尋址。

  • 引用比指針使用起來相對安全。

命名空間

在C++中,變量、函數(shù)和類都是大量存在的,這些變量、函數(shù)和類的名稱將都存在于全局命名空間中,會導致很多沖突,使用命名空間的目的是對標識符的名稱進行本地化,以避免命名沖突或名字污染。

  • 命名空間的定義

//命名空間namespace N1
{    int a = 30;    void FunTest()
    {        printf("N1::FunTest()\n");
    }
}//N1的命名空間int a = 20;void FunTest()
{    printf("::FunTest()\n");
}//在全局作用域中int main()
{    int a = 10;    printf("%d\n", a);    printf("%d\n", ::a);
    ::FunTest();    printf("%d\n", N1::a);
    N1::FunTest();    return 0;
}//命名空間的嵌套namespace N2
{    int a = 40;    void FunTest()
    {        printf("N2::FunTest()\n");
    }    namespace N3
    {        int a = 50;        void FunTest()
        {            printf("N2::N3::FunTest()\n");
        }
    }
}int main()
{
    N2::FunTest();
    N2::N3::FunTest();    return 0;
}// 在同一個工程里允許存在多個相同名稱的命名空間,編譯器最后會合成到同一個命名空間中namespace N1
{    int b = 70;    void Test()
    {        printf("N1::Test()\n");
    }
}
  • 說明
    a.一個命名空間就定義了一個新的作用域,命名空間中的所有內(nèi)容都局限于該命名空間中。
    b.沒有名稱的命名空間只能在當前文件中使用,它里面定義的變量相當于工程里面的全局變量。

  • 命名空間的使用

//命名空間的使用namespace N1
{    int a = 1;    int b = 2;    int c = 3;    /*void FunTest1()
    {}
    void FunTest2()
    {}*/}//法二:using N1::b;//法三:using namespace N1;int main()
{    int a = 4;    //法一:
    printf("a=%d\n", N1::a);//a=1

    printf("b=%d\n", b);//b=2
    printf("c=%d\n", c);//c=3}
C++輸入輸出:

//代碼

//C++輸入輸出#include <iostream>using namespace std;//std標準命名空間int main()
{    int a = 10;    double b = 3.14;    char c = 'c';    cout << a ;    cout << b << '\n';    cout << c << endl;    cout << a << " " << b << " " << c << endl;    cin >> a ;    cin >> b >> c;    return 0;
}// cout:標準命名空間重輸出流對象  <<輸出操作符   // cin:標準命名空間重輸入流對象   >>輸入操作符

感謝各位的閱讀!看完上述內(nèi)容,你們對C/C++區(qū)別是什么大概了解了嗎?希望文章內(nèi)容對大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI