您好,登錄后才能下訂單哦!
C/C++區(qū)別是什么?這個問題可能是我們?nèi)粘W習或工作經(jīng)常見到的。希望通過這個問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!
C/C++應該從關(guān)鍵字的個數(shù)、源文件、變量定義或聲明位置、函數(shù)、缺省參數(shù)幾個方面進行比較,如果你總是搞混,看了這篇文章會幫助到你。
C/C++從以下幾個方面的比較:
關(guān)鍵字的個數(shù):
C語言:C99版本,32個關(guān)鍵字
C++:C98版本,63個關(guān)鍵字
源文件:
C源文件后綴.c,C++源文件后綴.cpp,如果在創(chuàng)建源文件時什么都不給,則默認是.cpp
變量定義或聲明位置:
C語言必須在第一行定義;C++不做要求
函數(shù):
(1)返回值
C語言中,如果一個函數(shù)沒有指定返回值類型,默認返回int型;
C++中,對于函數(shù)返回值的檢測更加嚴格,如果一個函數(shù)沒有返回值,則必須指定為void.
(2)參數(shù)列表
C語言中,如果函數(shù)沒有指定參數(shù)列表時,默認可以接受任意多個參數(shù);但在C++中,因為嚴格的參數(shù)類型檢測,沒有參數(shù)列表的函數(shù),默認為void,不接受任何參數(shù)。
缺省參數(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ù)重載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++輸入輸出#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è)資訊頻道。
免責聲明:本站發(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)容。