C++語言誕生20年來,在經過前10年的爆發性增長,後10年的使用人數一直在穩定的增長。作爲有着20多年積累的程式設計語言,C++有着大量的技術沉澱,使得C++在現代軟體領域中佔據着舉足輕重的地位,其應用領域也越來越廣。C++的應用領域主要集中在以下幾個方面。
(1)遊戲:C++具有超效率,而且近年來C++憑藉先進的數值計算庫、泛型程式設計等優勢,在遊戲領域應用頗多。目前,除了一些網頁遊戲,很多遊戲用戶端都是基於C++開發的。
(2)網路軟體:C++擁有很多成熟的用於網路通訊的庫,其中最具代表性的就是跨平臺的、重量級的ACE庫,該庫可以說是C++語言最重要的成果之一,在許多重要的企業、部門甚至是軍方都在應用。
(3)伺服器端開發:很多網際網路公司的後臺伺服器都是基於C++開發的,而且大部分是Linux、Unix等類似操作系統,需要熟悉Linux操作系統及其在上面的開發,熟悉數據庫開發,精通網路程式設計,而這些技術都離不開C++的支援。
(4)嵌入式系統:因爲C++具有較高的效率,而且保持着對C語言的相容性,能使底層平臺有很高的效率,同時具有很大的靈活性,使得它在底層開發中有着極大的應用。另外C++在軟體拓展、移植維護上也有很好的表現。
(5)系統級開發:在該領域,C語言是主要的程式語言,但C++憑藉對C的相容,應用於底層開發可以用來編寫驅動程式,因此可以用來開發系統級軟體,編寫操作系統。
除此之外,C++在數位影像處理、虛擬現實模擬等方面都有着廣泛的應用,我們可以用一張圖來概括C++的應用領域,如圖1所示。
圖1 C++應用領域
當然,C++的應用不止於這些圖文說明,隨着資訊化、智慧化、網路化的發展,嵌入式系統技術的發展,C++語言的應用會越來越多,在各個應用領域都將發揮重要的作用。
寫C++程式的方式思路
用Visual Studio2013來編寫一個最簡單的C++程式,首先要建立一個C++源程式hello.cpp,其具體實現步驟和建立C語言原始檔一樣,具體建立步驟本書不再重複,注意C++原始檔的擴充套件名是「.cpp」。
在建立的原始檔中編寫C++程式,具體程式碼如例1所示。
例1
1 #include <iostream>
2 using namespace std;
3 int main()
4 {
5 cout << "hello C++" << endl;
6 system("pause");
7 return 0;
8 }
執行結果如圖1所示。
圖1 例1-1執行結果
例1就是一個完整的C++語言程式,接下來針對該程式中的主要語法進行詳細講解,具體如下:
1、iostream檔案
例1-1中第1行程式碼包含了輸入輸出標頭檔案 iostream,它是標準的C++標頭檔案,在舊的標準C++中,使用的是iostream.h,實際上這兩個檔案是不同的,在編譯器include資料夾裡它是兩個檔案,並且內容不同。在C++標準明確提出不支援後綴爲.h的標頭檔案,早期在C++中呼叫.h標頭檔案其實相當於呼叫的C標準庫,爲了和C語言區分開,C++標準規定不使用後綴.h的標頭檔案,例如C語言中的string.h標頭檔案,C++用string,C語言中的math標頭檔案,C++使用cmath標頭檔案。這不只是形式上的改變,其實現也有所不同。
2、名稱空間
第二行程式碼是參照全域性名稱空間,在講解全域性名稱空間之前,先來學習一下什麼是名稱空間。名稱空間實際上是由程式設計者命名的記憶體區域,程式設計者可以根據需要指定一些有名字的空間區域,把一些自己定義的變數、函數等識別符號存放在這個空間中,從而與其他實體定義分隔開來。其定義格式如下所示:
namespace 空間名{……}
namespace是定義名稱空間的關鍵字,空間名可以用任意合法的識別符號,在{}內宣告空間成員,例如定義一個名稱空間A1,程式碼如下所示:
namespace A1
{
int a = 10;
}
則變數a只在A1空間內({}作用域)有效,名稱空間的作用就是建立一些互相分隔的作用域,把一些實體定義分隔開來,就像三個名字相同的同學,如果分在一個班級裡,則點名時就會出現不確定性,如果將他們分在不同的班級則再點名時就沒有歧義了。
當名稱空間外的作用域要使用空間內定義的識別符號時,有三種方法可以使用:
(1)用空間名加上作用域識別符號「::」來標識要參照的實體,例如要參照上述A1空間中的變數a。
cout<<A1::a;
在參照處指明變數所屬的空間,就可以對變數進行操作了。
(2)使用using關鍵字,在要參照空間實體的上面,使用using關鍵字引入要使用的空間變數。
using A1::a;
cout<<a;
這種情況下,只能使用using引入的識別符號,如果A1空間裡還有識別符號b,則這個地方只引入了a, 則b不能被使用,但可以使用A1::b的形式。
(3)使用using關鍵字直接引入要使用的變數所屬的空間,例如:
using namespace A1;
這樣引入A1空間後,則A1中定義的所有實體都可以被參照了。但這種情況如果參照多個名稱空間
往往容易出錯,例如,定義了兩個名稱空間,兩個空間都定義了變數a,範例程式碼如下所示:
namespace A1
{
int a = 10;
}
namespace A2
{
int a = 20;
}
using namespace A1; //引入A1名稱空間
using namespace A2; //引入A2名稱空間
cout<<a; //引起編譯錯誤
這樣在輸出a時就會出錯,因爲A1與A2空間都定義了a變數,參照不明確,編譯出錯。因此只有在使用名稱空間數量很少,以及確保這些名稱空間中沒有同名成員時才用using namespace語句。
在編寫C++程式時,由於C++標準庫中的所有識別符號都被定義於一個名爲std的namespace中,所以std又叫作標準名稱空間,要使用其中定義的識別符號就要引入std空間。早期的實現將標準庫功能定義在全域性空間,宣告在帶iostream.h標頭檔案裡,包含iostream.h標頭檔案就可以使用全域性名稱空間中的識別符號。而現在的iostream標頭檔案沒有定義全域性名稱空間,如果要使用名稱空間中的識別符號,就要單獨引入std空間。
對於名稱空間的三種參照,顯而易見,第三種選擇更爲方便。在編寫大型專案時,往往是很多程式設計師編寫很多原始檔,函數名、變數名等難免會重複,如想使用一個變數num時,系統中存在兩個num變數,這時就可以將它們歸屬到不同的名稱空間space1、space2中,在使用時就可以用不同的名稱空間來區分它們,如:space1::num,space2::num。
多學一招:匿名名稱空間
名稱空間還可以定義成匿名的,也就是在申請的時候不寫名字,由系統自動分配。例如下面 下麪的匿名名稱空間:
namespace
{
int a;
}
編譯時,編譯器在內部會爲這個名稱空間生成一個唯一的名字,而且還會爲這個匿名的名稱空間生成一條using指令。所以上面的程式碼在編譯後等效於下面 下麪的程式碼:
namespace _UNIQUE_NAME
{
int a;
}
using namespace __UNIQUE_NAME_;
這個匿名的空間具有一個很有用的特性,那就是對於不同的編譯單元(cpp檔案),「同一個」匿名空間中的物件,會被當作不同的實體。而這個特性和全域性的static修飾是一致的,即相當於在這個源程式中定義了一個static int a;也就是隻能在當前檔案中參照a,而外部是不可見的。
由於static不能修飾型別定義,如class,而且static用在不同的地方有不同的含義,很容易造成混淆,所以相對於static,C++更傾向於使用匿名空間。
3、cin與cout
當例1-1中的第5行程式碼在螢幕上輸出「hello C++」時,讀者或許會吃驚,爲什麼不是printf()。其實printf()函數也可以,但它是C語言的標準輸出函數。在C++中輸入輸出都是以「流」的形式實現的, C++定義了iostream流類庫,它包含兩個基礎類istream和ostream來表示輸入流和輸出流它們分別定義了標準輸入流物件cin來處理輸入,標準輸出流物件cout來處理輸出。
cin與提取運算子「>>」結合使用,用於讀入使用者輸入,以空白(包括空格、回車、TAB)爲分隔符。
cout與插入運算子「<<」結合使用,用於列印訊息。通常它還會與操縱符endl使用,endl的效果是結束當前行,並將與裝置關聯的緩衝區(buffer)中的數據重新整理到裝置中,保證程式所產生的所有輸出都寫入輸出流中,而不是僅停留在記憶體中。
爲了讓讀者瞭解cin、cout的使用,接下來由使用者輸入兩個數實現兩個數相加,如例2所示。
例2
1 #include <iostream>
2 using namespace std;
3 int main()
4 {
5 int num1, num2;
6 cin >> num1 >> num2;
7 cout << num1 << "+" << num2 << "=" << num1 + num2 << endl;
8 system("pause");
9 return 0;
10 }
執行結果如圖2所示。
圖2 例1-2執行結果
在例2中,用cin連續輸入兩個整數,cout輸出兩值相加結果的表達式,關於cin與cout的用法很簡單,關於它的定義將在後面I/O流中講解,這裏讀者只需能夠使用即可。