C與C++的差異
c語言是結(jié)構(gòu)化模塊化的語言,是面向過程的程序設(shè)計。c++既可以面向過程,也可以面向?qū)ο蟮某绦蛟O(shè)計(增加了面向?qū)ο髾C制)。c語言的頭文件都有.h后綴名,c++中用戶自己編制的頭文件帶.h,系統(tǒng)提供的頭文件無后綴名,c++兼容c的頭文件。c語言的結(jié)構(gòu)體struct只能包含數(shù)據(jù)成員,c++的類可以包含數(shù)據(jù)成員和成員函數(shù)。c++中使用usingnamespace作為命名空間,當(dāng)含有系統(tǒng)頭文件時必須包含命名空間。
相對于c語言,c++語言增加的主要特性包括類、重載、派生、虛函數(shù)、模板以及異常處理。 但在進一步討論這些新特性之前,我們需要討論這兩種語言之間的一些小差異。
一、注釋
c++語言支持單行注釋。單行注釋由//開始,在之后的第一個換行符處結(jié)束。單行注釋比c語言的注釋更安全,因為他們不會意外丟掉注釋結(jié)束的標(biāo)記,但c語言的注釋在c++中任然是合法的。
二、標(biāo)記與類型名
在c++語言中用于標(biāo)識特定的結(jié)構(gòu)、聯(lián)合或枚舉的名字會自動被認(rèn)為是類型名。因此我們將
typedef struct {double re, im;} complex;
簡單寫成
struct complex {double re, im;} ;
三、不帶參數(shù)的函數(shù)
在聲明和定義一個不帶參數(shù)的c++函數(shù)時,可以不使用void:
void draw(void); //no arguments
void draw(); //no arguments either
四、默認(rèn)實際參數(shù)
c++語言允許函數(shù)的實際參數(shù)有默認(rèn)值。例如,下面的函數(shù)可以顯示任意個數(shù)的換行符。如果調(diào)用時沒有提供任何實際參數(shù)函數(shù)會顯示一個換行符。
void new_line(int n=1)
{
while (n-- > 0)
putchar('\n');
}
調(diào)用new_line函數(shù)時,可以提供一個實際參數(shù),也可以不提供實際參數(shù)。
new_line(3); //print 3 blank lines
new_line(); //print 1 blank line by default
五、引用參數(shù)
c語言規(guī)定實際參數(shù)是按值傳遞的,這使編寫那些需要修改作為實際參數(shù)提供的變量(除了數(shù)組)都非常困難。為了回避這個限制,我們只能傳遞指向該變量的指針。對于一個將兩個變量的內(nèi)容交換的函數(shù),其C語言的實現(xiàn)大致如下:
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
當(dāng)swap函數(shù)被調(diào)用時,其參數(shù)應(yīng)該是指向變量的指針:
swap(&i, &j);
雖然這種方式可以正常工作,但它使用起來并不方便,代碼也不易理解,還容易出錯。c++語言在這方面做一些改進,允許實際參數(shù)被聲明成引用,而不是指針。下面是將a和b聲明為引用后swap函數(shù)的樣子:
void swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}
當(dāng)swap函數(shù)被調(diào)用時,不需要在實際參數(shù)前加&運算符:
swap(i, j);
在swap的函數(shù)體中,a和b被分別理解為i和j的別名。語句temp=a確實會將i的值復(fù)制到temp中。語句a=b也確實將j的值復(fù)制到i中。同樣,b=temp將temp的值復(fù)制給j。
當(dāng)看到&a這樣的形式時,怎樣區(qū)別是聲明引用變量還是取地址的操作呢?
請記住,當(dāng)及a的前面有類型符時(如int &a),它必然是對引用的聲明;如果前面沒有類型符(如p= &a),此時的&是取地址運算符。
六、動態(tài)存儲分配
c程序可以使用函數(shù)malloc、calloc、realloc動態(tài)分配和釋放內(nèi)存。雖然c++程序仍然可以使用這些函數(shù),但更好的做法是使用new和delete。 new和delete是運算符,不是函數(shù)。new用來分配空間,delete用來釋放分配的空間。new的操作數(shù)是一個類型說明符:
int *int_ptr , *int_array;
int_ptr = new int;
int_array = new int[10];
當(dāng)無法分配所要求的內(nèi)存時,new會返回空指針。delete需要用一個指針作為他的操作數(shù):
delete int_ptr;
delete [ ] int_array;
七、輸入輸出
相比于c,c++增加了自己的輸入輸出流cin和cout(endl作為換行機制可以使用\n替換)。c中的scanf和printf為函數(shù),而cin和cout為對象。cout不需要對輸出數(shù)據(jù)進行格式控制,系統(tǒng)會自動按照數(shù)據(jù)類型輸出;cin有一些格式控制功能。
八、函數(shù)的重載
c語言中,在同一作用域不能包含同名函數(shù);c++中可以,這些同名函數(shù)中參數(shù)的個數(shù)或類型必須不同,返回值類型可以相同可以不同。(函數(shù)重載)
九、函數(shù)模板
函數(shù)的重載只是形參的類型或個數(shù)不同,也要分別定義。對此能否再簡化呢?為了解決這個問題,C++提供了函數(shù)模板(function template)。所謂函數(shù)模板,實際上是建立一個通用函數(shù),其函數(shù)類型和形參類型不具體指定,用一個虛擬的類型來代表。這個通用函數(shù)就稱為函數(shù)模板。凡是函數(shù)體相同的函數(shù)都可以用這個模板來代替,不必定義多個函數(shù),只須在模板中定義一次即可。在調(diào)用函數(shù)時系統(tǒng)會根據(jù)實參的類型來取代模板中的虛擬類型,從而實現(xiàn)了不同函數(shù)的功能。模板類聲明如下:
template<class T>
類型參數(shù)可以不只一個,可根據(jù)需要確定個數(shù)。如template<class T1,typename T2>
T max(T a,T b,T c) //定義一個通用函數(shù),用T作虛擬的類型名
{
if(b>a)a=b;
if(c>a)a=c;
return a;
}
十、總結(jié)
綜上所述,c++對c功能的擴展包括:
(1)允許使用以“//”開頭的注釋。
(2)對變量的定義可以出現(xiàn)在程序中的任何行(但必須在引用該變量之前)。
(3)提供了標(biāo)準(zhǔn)輸入輸出流cin和cout,它們不用指定輸入輸出格式符(如%d),使輸入輸出更加方便。
(4)可以用const定義常變量。
(5)可以利用函數(shù)重載實現(xiàn)用同一函數(shù)名代表功能類似的函數(shù),以方便使用,提高可讀性。
(6)可以利用函數(shù)模板,簡化同一類型的函數(shù)的編程工作。
(7)可以使用帶默認(rèn)值的參數(shù)的函數(shù),使函數(shù)的調(diào)用更加靈活。
(8)提供變量的引用類型,即為變量提供一個別名,將“引用”作為函數(shù)形參,可以實現(xiàn)通過函數(shù)的調(diào)用來改變實參變量的值。
(9)增加了內(nèi)置函數(shù)(內(nèi)嵌函數(shù)),以提高程序的執(zhí)行效率。
(10)增加了單目的作用域運算符::,這樣在局部變量作用域內(nèi)也能引用全局變量。
(11)可以用string類定義字符串變量,使得對字符串的運算更加方便。
(12)用new和delete運算符代替malloc和free函數(shù),使分配動態(tài)空間更加方便。