#
3. 更改語句
在各種循環結構中,總是有一個循環控制變量用來構成循環是否繼續執行的條件。例如前面例子中的nInout就是一個循環控制變量,可以用它的值來判斷是否需要進行下一次的循環。既然是表示循環的條件,就需要在循環中對這個變量進行修改,以反映循環的執行情況,根據執行情況決定循環是否繼續進行。例如將用戶輸入的值賦值給nInput,就是對循環控制變量的修改。for循環是將循環控制變量的修改獨立出來放到了更改語句中來進行。
在理解了for循環的三個要素之后,再來理解for循環的執行流程就比較清楚了。程序進入for循環語句之后,首先會執行初始化語句,完成必要的初始化工作。然后再計算條件表達式的值,如果條件表達式的值為true,則執行循環體語句,再執行更改語句,修改循環控制變量。接著又開始計算條件表達式的值,根據其值決定是否需要繼續下一次循環:如果條件表達式的值為true,則繼續下一次循環;反之,則結束整個循環的執行。for循環控制結構的執行流程如圖4-5所示。
圖4-5 for循環的執行流程
The world is built on 了解C++.
——Herb Sutter
?
看得有趣、學得輕松
?看圖也能學C++?!
沒錯,看圖也能學C++!
這本迷你書是《我的第一本C++書》的迷你版,它抽取了《我的第一本C++書》中的全部的精美插圖,并配上相應的解釋說明。它以圖文并茂的生動形
式,向你講解那些所謂的高深的C++知識,讓你對那些抽象的C++知識有一個更加形象的理解,向你展示這個美麗而神秘的C++世界,讓你在有趣的看圖過程
中,輕松地學到了C++知識。

看得有趣、學得輕松?
免費下載
3.9.3 指針的賦值和使用
在得到一個指針變量之后,指針變量的值還是一個隨機值。這個值可能是內存中無關緊要的數據,也可能是重要的數據或者程序代碼,如果直接使用是很危險的,所以在使用指針之前,必須對其進行賦值,將其指向某個有意義的數據或代碼。對指針變量進行賦值的語法格式如下:
指針變量 = 內存地址;
可以看到,對指針變量的賦值,實際上就是將這個指針指向某一內存地址,而這個內存地址上存放的就是這個指針想要指向的數據。通常我們用一個變量來保存數據,那么該如何方便地得到一個變量在內存中的地址呢?反過來,如果知道一個指針,又如何取出存放在其中的數據呢?為了解決這兩個問題,C++提供了兩個與內存地址相關的運算符——“&”和“*”。
1. “&”運算符
“&”稱為取地址運算符,如果把它放在一個變量的前面,則可以得到該變量在內存中存放的地址。例如:
// 定義一個整型變量
int N = 703;
// 取得整型變量的地址并將其賦值給整型指針
int*pN = &N;
通過“&”運算符可以取得N這個整型變量的內存地址,然后將其賦值給指針pN,也就是將指針pN指向N這個整數數據,如圖3-7所示。

圖3-7 指針和指針所指向的數據
4.2.2 并列的選擇:switch語句
其中,條件表達式就是要進行判斷的條件。switch語句首先計算條件表達式的值,這個表達式的值只能是整型或字符型。完成這個表達式的計算之后,程序開始在各個“case”分支中從上到下逐個匹配,查找哪個常量值和這個表達式的值相等。如果找到相等的常量表達式,則以此為入口開始往下順序執行case分支中的語句,直到遇到break關鍵字,完成整個switch語句的執行。如果查找所有case分支都沒有找到相等的常量表達式,則進入表示默認情況的default分支開始執行,最終完成整個switch語句。default關鍵字是可選的,如果沒有default關鍵字,在程序找不到匹配的case分支后,則直接結束switch條件選擇語句的執行,如圖4-2所示。

圖4-2 switch語句的執行流程
更多來自:http://imcc.blogbus.com
3.9.1 指針的本質:表示內存地址的數據類型
在典型的32位平臺上,可以把內存空間看成是由很多個連續的小房間構成的,每個房間就是一個小存儲單元,大小是1個字節,房間中住著數據。有的數據比較小,比如一個char類型的字符,它只需要一個房間就夠了。而有的數據比較大,就需要占用好幾個房間,比如一個int類型的整數,其大小是4個字節,需要4個房間才可以安置。為了方便找到住在這些房間中的數據,房間就需要按照一定的規則編號,這個編號,就是通常所說的內存地址。這些編號是用一個32位的二進制數來編碼的,比如0x7AE4074B、0xFFFFFFFF等,如圖3-6所示。一旦知道某個數據的房間編號,就可以通過這個編號來對相應房間中的數據進行存取操作。C++中為了靈活地操作內存,特別內建了一種特殊的數據類型,以用來存放內存單元的地址,這就是指針。而存放在指針中的內存地址,則可能是一個對象的地址、一個整數的地址,甚至是一個函數的地址。一般來說,如果指針變量所保存的是一個對象或者函數的地址,就說這個指針指向這個對象或者函數。

圖3-6 內存被劃分為許多小的單元房間
更多來自:http://imcc.blogbus.com
3.8.1 打包復雜:結構體的定義
其中,struct關鍵字表示要創建一個結構體,結構體名就是要創建的新結構體的名字,通常使用結構體描述的事物來作為結構體的名字。在結構體的內部,我們分別使用多個不同數據類型的變量來表示復雜事物的各個屬性。因為這些變量共同組成了結構體,所以這些變量稱為結構體的成員變量。有了結構體,就可以在結構體中定義多個不同類型的成員變量,從各個屬性來描述一個復雜的事物。例如,可以這樣來定義描述人這個復雜事物的結構體:
// 定義結構體Human描述人這個復雜事物
struct Human
{
string m_strName; // 姓名
bool m_bMale; // 性別
int m_nAge; // 年齡
int m_nHeight; // 身高
float m_fWeight; // 體重
};
以前是用各個基本數據類型的變量來分別描述一個復雜事物的各個屬性。這里是將變量集合在一起,打包成一個結構體,如圖3-5所示。有了結構體,就可以定義一個統一的結構體變量來描述一個具體的復雜事物,代替原來定義多個變量描述同一個事物。例如:
// 定義一個Human結構體變量描述“陳良喬”這個人
// 這個結構體包含了他的姓名、性別和年齡等信息
Human chenliangqiao;

圖3-5 將復雜事物打包成結構體
更多來自:http://imcc.blogbus.com
3.6.1 排排坐,吃果果:數組的聲明與初始化
我們常常遇到這樣的數據:數量很大;有相同的數據類型;有相同的處理方式。例如,一個公司所有員工的工資、一個學校所有學生的成績、一個地區一年的氣溫,等等。為了描述這種量大且相似的數據,C++提供了數組這種構造型數據類型。
如果把整個內存看成是一座賓館,那么可以把數組看成是某一層樓上的一個個連續的小房間。這些小房間具有相同的容量,可以存放相同數據類型的數據。當然,房間容量的不同或者連續房間個數的不同,可以在內存中形成不同的數組,如圖3-2所示。


圖3-2 數組就是內存中的多個小房間
更多來自:http://imcc.blogbus.com
第3章
Ÿ C++世界眾生相
在聽過了HelloWorld.exe的自我介紹,完成了與C++的第一次親密接觸后,大家是不是都急不可待地想要一試身手,開始編寫C++程序了呢?
我們知道,程序首先是使用數據來描述現實世界的。當我們嘗試使用數據來描述現實世界時,馬上就遇到了一個問題:C++世界中的數據這么多,我們一個都不認識,該從哪里開始啊?別著急,現在我就來為你們介紹C++世界的蕓蕓眾生:基本數據類型。
3.1 百家姓:C++中的數據類型
我們知道,編程是使用程序設計語言來描述和表達現實世界的。現實世界中有很多客觀存在的事物,例如數字、人、車輛等。很多數據是同一類的,比如人的名字,都是由文字構成的;人的身高,都是由數字組成的。在程序設計語言中,我們將這些相同類型的數據抽象成數據結構。數據結構是對現實世界中的同類數據的描述,我們把它也稱為數據類型。這就像現實世界中人的姓氏一樣,同一個姓氏的人是一家人。在C++世界中,同樣數據類型的數據是同一個類別的,也有著相同的一些特征。為了描述現實世界中豐富多樣的事物,通常將這些事物定義成具體的數據,而數據類型則是這些事物的種類。數據類型就像C++世界的百家姓,一個數據的數據類型,決定了這個數據是哪一家的人,如圖3-1所示。

圖3-1 C++的和諧大家庭
2.2.3 讀寫文件
在這段程序中,我們首先創建了一個輸入文件流ifstream的對象fin,并利用它的構造函數將其連接到一個文本文件Date.txt。所謂構造函數,就是這個對象創建的時候所執行的函數。這里,我們使用“Date.txt”作為參數來調用這個構造函數,實際上就是使用這個文件創建fin對象。除此之外,我們還可以使用fin所提供的open()函數來打開一個文件。當我們利用fin成功打開一個文件之后,就可以利用提取符“>>”從fin中提取各種數據。“>>”會以空格為分隔符逐個從文件中讀取數據并將其保存到相應的數據變量中。例如,如果文件中的內容如下:
用戶輸入的當前日期是:
1983 7 3
默認情況下,fin總是從文件的開始部分進行讀取的,為了直接讀取第二行的內容,我們使用“fin.ignore(256,'\n');”忽略了第一行的內容,將讀取位置跳轉到第二行。然后,通過提取符“>>”,我們將第二行用空格分割的三個數據分別提取并保存到了三個變量中。
同樣,為了將數據寫入文件,我們需要創建一個輸出文件流ofstream的對象fout,然后通過它的構造函數或者是open()函數來打開一個文件,將這個文件和fout對象連接起來,然后通過插入符“<<”將數據插入到fout對象,也就實現了將數據寫入到它所關聯的文件中的目的。整個過程如下圖2-9所示:

圖2-9 文件讀寫
2.1.6 我的人生目的:描述數據與處理數據
每個人都會問自己人生的目的是什么?我的人生目的是什么?人們編寫程序的目的,是為了用程序解決現實世界中的問題。人們觀察發現,這些問題都是以數據作為輸入,然后對這些數據進行處理,最后得到問題的結論。所以,我人生的目的是描述數據并處理數據,最終解決現實世界的問題,如圖2-8所示。

圖2-8 我的人生目的