細數C++和C的區別
C++語言是對C語言的擴充套件。所以熟悉C語言的人會發現,本書的第01~18章講的內容基本上和C語言的內容差不多。C++一方面對C語言的語法進行了修改,另一方面又新增一些新的概念。
C++中新增的概念有:bool型別、引用(14章)、類(19~24章)、模板(25~26章)、異常(27章)。
C++相對於C有變化的語法點有:變數分散定義、函式名過載、struct語法。本章著重是比較分析這幾個有變化的語法點。
本篇選自《C/C++學習指南》,附錄14
權利宣告:作者擁有本書的全部權利。作者授權任何人都可以自由轉載本網站釋出的內容,但轉載時必須遵守以下限制:①轉載時必須全文轉載,不得有任何修改,必須包含
1.1 在專案裡新增c檔案
當檔案以.c作為字尾時,編譯器以C語言的語法對該檔案進行編譯;當檔案以.cpp作為字尾時,編譯器以C++的語法標準對其進行編譯。所以,檔案的字尾名是有這個約定的,不能夠隨便更改。
在新增檔案時,輸入檔名的字尾是.c,那在編輯這個檔案時必須遵守C語言的語法,如下圖所示,
1.2 變數分散定義
這一點在第8章介紹函式略有介紹。
在C語言中,所有的區域性變數必須在函式或複合語句的最前面集中定義,簡單地說就是變數定義語句要放在前面。不然就報語法錯誤。
下面的main.c(C語言)程式碼中,區域性變數a,b的均在函式體的前部定義,因而符合C語言的語法要求,
////////////// main.c ////////// #include <stdio.h> void main() { int a; // 變數定義 int b; // 變數定義 a = 10; printf("a=%d \n", a); b = 11; printf("b=%d \n", b); }
下面的main.c(C語言)程式碼中,區域性變數c的定義沒有放在前面,不符合C語言的語法要求,因而編譯報錯,
////////////// main.c //////////
#include <stdio.h>
void main()
{
int a; // 變數定義
int b; // 變數定義
a = 10;
printf("a=%d \n", a);
b = 11;
printf("b=%d \n", b);
int c ; // 變數定義語句不能放在這裡
c = a + b;
printf("c=%d\n", c);
}
顯然,這樣對於程式設計師來說是很不方便的。於是C++語言去掉了這個限制,讓程式設計師可以隨時隨地的定義變數。
1.3 函式名過載
C++允許多個函式使用相同的函式,這稱為函式名過載。而這在C語言中是萬萬不可以的,在C語言中,全域性函式名是不能重複的。例如,在下面的main.c檔案中,存在兩個名稱相同的全域性函式do_something,導致編譯器報錯,
////////////// main.c //////////
#include <stdio.h>
void do_something(int x, int y)
{
printf("int , int \n");
}
void do_something(double x, double y)
{
printf("double , double \n");
}
void main()
{
printf("test");
}
這個問題的本質是,在C語言中,以函式名來唯一區分一個全域性函式。換句話說,函式名就是函式的唯一ID,顯然ID這個東西是不能衝突的。
這導致了在C語言中,給函式起名字也成了一個比較麻煩的事情,對於功能類似的函式,由於不能起相同的名字,所以只好不停地加一些字尾以示區別,例如,
do_something_int_int()
do_something_double_double()
如果你將來閱讀一些C語言的程式碼,相信會有此感受。
C++針對此問題的改進是:以函式名+引數列表來唯一區分函式。所以,在C++中函式名是允許相同的,只要引數列表有所不同就不會衝突。
1.4 struct定義
在C語言中, struct型別的定義必須加上struct的字首,
而在C++中,struct可以直接使用其型別名來定義
相比之下,應該是C++的語法更簡潔一些。所以在用C語言編寫程式碼的時候,老是要加一個struct字首會讓人覺得不耐煩,所以C程式設計師通常是這麼來定義的struct的。在下面的程式碼中,使用typedef來定義一個object_t的型別,
在C語言的世界裡,這麼定義struct是通用模式,為的就是在使用的時候少寫一個struct字首。(可見C程式設計師有多麼無耐)。
在需要定義連結串列的時候,C程式設計師有兩種寫法,
struct Object
{
int id;
struct Object * next; //
};
或
typedef struct _tag_object
{
int id;
struct _tag_object * next;
}object_t;
同樣的,C程式設計師會選擇第二種定義方法,唯一目的就是為了在使用的時候少寫一個關鍵字struct而已。
1.5 C++中的struct
實際上,C++對struct進行提全面的升級,以至於C++的struct幾乎完全等效於class的語法了。凡是class支援的語法,包括成員函式、public/private、繼承等所有的語法,struct也都全部支援且意義不變。也就是說,struct是class的同義語(略有差別,後面講到)。
唯一的一點小區別:對於struct,如果沒有宣告任何修改符(public/protected/private),則預設所有成員是public的。這一點上class相反,class預設是private的。