版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、1本章提要7-1 甚麼是陣列?7-2 字元陣列7-3 多維陣列7-4 指標(biāo)與參照7-5 指標(biāo)與參考在函式上的應(yīng)用7-6 綜合演練27-1 甚麼是陣列?由於一個(gè)變數(shù)只能存放一個(gè)數(shù)值, 而針對(duì)有些用來(lái)處理大批資料 (如學(xué)生、員工資料等) 的程式, 就必須宣告許多的變數(shù)來(lái)存放這些資料。此時(shí)為了方便, 我們便可利用陣列來(lái)代替多個(gè)變數(shù)。使用陣列來(lái)代替變數(shù)的好處是可以讓程式碼容易撰寫(xiě)。因?yàn)橐粋€(gè)陣列可取代多個(gè)變數(shù)。比如說(shuō), 我們要用 10 個(gè)變數(shù)來(lái)儲(chǔ)存 10 個(gè)學(xué)號(hào), 以之前所學(xué)的方法可能要寫(xiě)成:3甚麼是陣列?4甚麼是陣列?如果改用陣列來(lái)儲(chǔ)存 10 個(gè)學(xué)號(hào), 會(huì)方便許多, 如下:陣列可說(shuō)是一群同型別與同性質(zhì)
2、變數(shù)的集合, 就等於一次宣告了多個(gè)變數(shù)的儲(chǔ)存空間。5宣告與定義陣列陣列的宣告方式和宣告一般變數(shù)一樣, 都要指明資料型別和變數(shù)名稱, 此外需在變數(shù)名稱後加上一對(duì)中括號(hào) (稱為足標(biāo)標(biāo)算子, subscript operator), 表示這是個(gè)陣列變數(shù)。並需在中括號(hào)內(nèi)填入陣列的容量, 表示可以容納多少個(gè)同型別的變數(shù):6宣告與定義陣列例如以下就是陣列宣告的例子:請(qǐng)注意, 宣告陣列時(shí)所指定的陣列大小, 必須是常數(shù) (含 const 變數(shù)) 或由常數(shù)組成的運(yùn)算式, 不可以是在編譯時(shí)期不能確定其值的變數(shù)或運(yùn)算式。換言之, 陣列大小是在宣告或定義時(shí)就固定的, 之後即無(wú)法改變其大小。7宣告與定義陣列陣列中每個(gè)可
3、用來(lái)存放資料的空間稱為元素, 例如上例中的 car, 我們就可稱它為是十個(gè)元素的整數(shù)陣列, 每個(gè)元素就像一個(gè)整數(shù)變數(shù)一樣, 可存放一筆整數(shù)資料。要使用元素時(shí), 需以陣列名稱及足標(biāo)運(yùn)算子, 並在足標(biāo)運(yùn)算子中指定元素的編號(hào) (或稱為元素的索引) 請(qǐng)注意, 元素的編號(hào)是從 0 開(kāi)始, 所以上列中的 car 陣列, 可使用的索引值是 09, 例如:8宣告與定義陣列以下程式簡(jiǎn)單示範(fàn)陣列宣告及存取陣列元素的語(yǔ)法:9宣告與定義陣列10宣告與定義陣列1. 第 6 行宣告可存放 5 個(gè)元素的整數(shù)陣列 iArray。11宣告與定義陣列2. 第 89 行利用 for 迴圈依序設(shè)定 iArray 各元素的值。請(qǐng)注意用
4、來(lái)當(dāng)元素索引值的變數(shù) i 是從 0 開(kāi)始, 而不是從 1 開(kāi)始。3. 第 1112 行輸出以 sizeof() 運(yùn)算子取得的 iArray 陣列大小。由於整數(shù)資料型別佔(zhàn)用 4 個(gè)位元組, 因此 5 個(gè)整數(shù)陣列元素即佔(zhàn)用 5x4=20 個(gè)位元組的記憶體空間。4. 第 1314 行再次以 for 迴圈依序輸出 iArray 各元素的值。12宣告與定義陣列使用迴圈來(lái)操作陣列是很常見(jiàn)的處理方法, 而為了避免在操作時(shí)不小心超出陣列元素的索引範(fàn)圍, 通常會(huì)先在程式開(kāi)頭定義一個(gè)代表陣列大小的唯讀變數(shù)或常數(shù), 之後在程式中都使用這個(gè)唯讀變數(shù)或常數(shù)來(lái)表示陣列大小及索引範(fàn)圍, 以減少程式碼出錯(cuò)的情形, 例如前面的
5、範(fàn)例可寫(xiě)成:13宣告與定義陣列14設(shè)定陣列初值我們可在定義變數(shù)時(shí)用指定運(yùn)算子設(shè)定變數(shù)初始值, 而陣列由於有許多元素, 所以設(shè)定初始值的方式略有不同。要設(shè)定陣列元素初始值時(shí), 需用大括號(hào)括住各初始值, 並從第 0 個(gè)元素依序開(kāi)始設(shè)定, 語(yǔ)法如下:例如:15設(shè)定陣列初值定義陣列及元素初始值時(shí), 有幾點(diǎn)注意事項(xiàng):1. 有設(shè)定初始值時(shí), 可不指定陣列大小。此時(shí)元素個(gè)數(shù)就是大括號(hào)中的初始值個(gè)數(shù), 例如 int a =1,2,3; 表示 a 的大小為 3 個(gè)元素。2. 若有指定陣列大小時(shí), 則初始值的數(shù)量需小於或等於元素個(gè)數(shù)。只指定部份元素的初始值時(shí), 未指定到初始值的元素其初始值一律為 0 (若是字元型
6、別的陣列, 則為 0);初始值的數(shù)量若超過(guò)元素個(gè)數(shù), 則編譯時(shí)會(huì)出現(xiàn)錯(cuò)誤。以下就是定義陣列及元素初始值的範(fàn)例:16設(shè)定陣列初值17設(shè)定陣列初值18設(shè)定陣列初值1. 第 6 行定義的 iArray 未指定陣列大小, 因此其元素個(gè)數(shù)依初始值個(gè)數(shù)定為 5。2. 第 7 行定義的 nArray 陣列大小為 5, 但只指定 3 個(gè)元素值, 因此後 2 個(gè)元素的值為 0, 由執(zhí)行結(jié)果可驗(yàn)證之。3. 第 912 行輸出以 sizeof() 運(yùn)算子分別取得的 iArray 與 nArray 陣列大小。由於整數(shù)資料型別佔(zhàn)用 4 個(gè)位元組, 因此 5 個(gè)整數(shù)陣列元素即佔(zhàn)用 5x4=20 個(gè)位元組的記憶體空間。19
7、設(shè)定陣列初值4. 第 1417 行再次以 for 迴圈分別依序輸出 iArray 與 nArray 中各元素的值。至此我們已介紹了陣列的基本使用方法, 讀者可將陣列當(dāng)成一般的變數(shù)來(lái)使用即可, 只不過(guò)要記得以下幾點(diǎn)差異:20設(shè)定陣列初值陣列相當(dāng)於多個(gè)同型變數(shù)的集合, 集合中的每個(gè)元素就是一個(gè)變數(shù)。陣列大小一經(jīng)設(shè)定後就不能改變, 但元素值則和變數(shù)一樣是隨時(shí)可更改的。陣列變數(shù)不可以指定給另一個(gè)陣列變數(shù), 例如:21陣列應(yīng)用認(rèn)識(shí)陣列的基礎(chǔ)後, 我們要進(jìn)一步介紹幾項(xiàng)陣列的基本應(yīng)用。由於陣列是一群資料的集合, 所以常被用於需處理多筆同類型資料的情況, 而在這種場(chǎng)合下有幾種應(yīng)用是很常見(jiàn)的, 例如搜尋某一筆特
8、定的資料、尋找最大或最小的元素、將所有元素依指定的順序排列等等。以下簡(jiǎn)介兩種陣列的應(yīng)用, 至於其它的應(yīng)用方式也都很類似, 讀者可自行舉一反三。22尋找陣列中的最大或最小值在處理多筆資料時(shí), 時(shí)常需要找出其中的最大或最小值。最簡(jiǎn)單的方法就是用迴圈將所有元素一一比較, 全部都比對(duì)過(guò)後, 即可找出最大或最小的元素。例如在下面的範(fàn)例中, 將在使用者輸入的 5 個(gè)數(shù)值中找出最大值:23尋找陣列中的最大或最小值24尋找陣列中的最大或最小值25尋找陣列中的最大或最小值1. 第 1114 行的迴圈是用來(lái)控制請(qǐng)使用者輸入 5 個(gè)數(shù)字, 並依序存入 numbers。2. 第 16 行定義代表最大值的變數(shù), 並先將
9、其值設(shè)為 numbers0 的值。3. 第 1921 行的迴圈是用來(lái)挑出最大值, 此迴圈會(huì)依序?qū)?MAX 與陣列中 numbers0 以外的所有元素做比較, 若其值比 MAX 大, 就將它的值指定給 MAX。26將陣列內(nèi)所有元素排序所謂排序, 就是將一串隨意排列的同類型資料, 利用迴圈與條件式比較大小後, 將它重新依由小到大的昇冪或者由大到小的降冪方式排列。這個(gè)處理方式比前面單純找出最大 / 最小值更為實(shí)用, 因?yàn)榕判蜥嵋部梢院苋菀渍页鲎畲?/小值 (第 1 個(gè)或最後 1 個(gè)元素), 進(jìn)一步延伸, 就能馬上變成找最大或最小的前數(shù)筆資料。27將陣列內(nèi)所有元素排序在排序方法中, 最普通的排序法稱為
10、汽泡排序法 (Bubble Sort)。因?yàn)樵谂判蜻^(guò)程中, 數(shù)值較大的元素其位置會(huì)漸漸的往前面移動(dòng), 就好像一個(gè)氣泡由水底浮到水面, 因?yàn)閴毫p小, 氣泡的體積會(huì)慢慢變大一般, 這就是其名稱的由來(lái)。以下程式是由一個(gè)包含 5 個(gè)元素的字元陣列, 利用氣泡排序法, 將 5 個(gè)字母由大到小排列, 程式如下:28將陣列內(nèi)所有元素排序29將陣列內(nèi)所有元素排序30將陣列內(nèi)所有元素排序氣泡排序法會(huì)先取第 1 個(gè)陣列元素, 與所有陣列元素比較後, 如果第 1 個(gè)陣列元素比第 2 個(gè)小, 則交換位置, 反之則不換。i 為 0 時(shí), 如下 圖 (字元大小的比較, 就是在比較其 ASCII 碼, s、c、i、o、n
11、 的 ASCII 碼分別為 115、99、105、111、110):31將陣列內(nèi)所有元素排序32將陣列內(nèi)所有元素排序接著 i 為 1 時(shí), 取第 2 個(gè)陣列元素與其後的所有元素比較, 如右圖:33將陣列內(nèi)所有元素排序以此類推, 排序直到全部元素都比較過(guò)為止, 如右圖:若要將陣列改成由小到大的排列方式, 只需將第 13 行的條件運(yùn)算子改成大於即可。347-2 字元陣列前面的例子使用到了字元陣列, 其實(shí)字元陣列還有個(gè)特殊的用途, 就是當(dāng)成字串 (String) 來(lái)使用。雖然這個(gè)用法是承襲自 C 語(yǔ)言, 而 C+ 本身也已專為字串的應(yīng)用提供了專用的類別, 但將字元陣列當(dāng)成字串使用仍相當(dāng)常見(jiàn), 因此本
12、節(jié)就來(lái)簡(jiǎn)介字元陣列的相關(guān)應(yīng)用。35可當(dāng)成字串的字元陣列由於字串和字元陣列一樣都是一組字元的集合, 所以我們可把字元陣列當(dāng)成字串使用。但首先必須要認(rèn)識(shí)的是, 對(duì) C+ 而言, 到底什麼是字串?我們已經(jīng)學(xué)過(guò), 用雙引號(hào)括起來(lái)的文字就是一個(gè)常數(shù)字串, 例如 I Love You, 用如下的敘述就能將這 10 個(gè)字元 (含空白字元) 輸出到螢?zāi)簧希?6可當(dāng)成字串的字元陣列但如果我們執(zhí)行如下的敘述:這時(shí)候所得到的結(jié)果是 11 而非 10。這是因?yàn)?對(duì) C+ 編譯器而言, 它在儲(chǔ)存 I Love You 這個(gè)字串時(shí), 除了儲(chǔ)存十個(gè)字元外, 還在字串結(jié)尾加上一個(gè)代表字串結(jié)尾的 0 字元 (ASCII 字碼
13、0, 而非數(shù)字 0), 所以 I Love You 在記憶體中所佔(zhàn)的空間是 11 個(gè)位元組而非 10 個(gè)位元組。37可當(dāng)成字串的字元陣列有了這個(gè)認(rèn)識(shí)後, 我們就知道字元陣列若要用來(lái)儲(chǔ)存字串也是一樣, 必須在陣列中多出一個(gè)元素來(lái)儲(chǔ)存代表字串結(jié)尾的結(jié)束字元, 否則就不能稱其為字串。在定義字元陣列時(shí), 可直接將字串內(nèi)容當(dāng)成初始值設(shè)定給陣列, 此時(shí)就不必再用大括號(hào)將字串括起來(lái), 請(qǐng)參考以下範(fàn)例。38可當(dāng)成字串的字元陣列39可當(dāng)成字串的字元陣列1. 第 6、7 行分別定義 2 個(gè)字元陣列, 但 name1 是直接以字串為其初始值;name2 則以分別指定各元素字元的方式設(shè)定初始值。2. 第 9、10 行
14、分別輸出兩個(gè)陣列的 sizeof( ) 運(yùn)算結(jié)果, 雖然兩者的字?jǐn)?shù)相同, 但 name1 最後還有個(gè)空白字元, 所以輸出結(jié)果為 11。3. 第 12、13 行則是以陣列名稱直接輸出, 對(duì) cout 而言, 若是字元陣列, 就會(huì)輸出其中所存放的字串內(nèi)容。40可當(dāng)成字串的字元陣列在輸出結(jié)果中, 比較奇怪的是用 cout 輸出 name2 的結(jié)果:Mary White, 最後面的字元 是從何而來(lái)的呢?其實(shí)以 cout 字元陣列名稱 的方式輸出字元陣列的內(nèi)容時(shí), 原則上 cout 是把它當(dāng)成字串來(lái)處理, 所以會(huì)輸出在結(jié)束字元 0 之前的所有字元, 也就是整個(gè)字串的內(nèi)容。41可當(dāng)成字串的字元陣列但本例中
15、 name2 陣列並沒(méi)有結(jié)束字元, 所以程式會(huì)以為字串還沒(méi)結(jié)束, 就接著輸出記憶體中放在 Mary White 之後的內(nèi)容, 直到遇到結(jié)束字元為止。在本例中, Mary White 之後先出現(xiàn)的是字元 隨後就是字元 0, 所以很幸運(yùn)地程式只輸出 Mary White 就沒(méi)有再輸出其它奇怪的文字了。這是使用字元陣列時(shí)可能會(huì)遇到的問(wèn)題, 必須小心處理, 否則會(huì)讓程式輸出一堆奇怪的內(nèi)容。42標(biāo)準(zhǔn)函式庫(kù)對(duì)字元陣列的支援前面提過(guò)陣列變數(shù)的一些限制, 例如陣列不能直接指定給另一個(gè)陣列, 所以若要把一個(gè)陣列的內(nèi)容複製到另一個(gè)陣列, 就需將來(lái)源陣列中的元素, 用迴圈一個(gè)個(gè)指定給目的陣列的元素。43標(biāo)準(zhǔn)函式庫(kù)對(duì)
16、字元陣列的支援但使用字串時(shí)常會(huì)遇到需搬移、複製字串或其它類型的應(yīng)用, 若都要自己用迴圈來(lái)一一處理, 實(shí)在很不方便, 因此在標(biāo)準(zhǔn)函式庫(kù)中就提供了許多字串相關(guān)的函式, 這些函式的宣告都放在 含括檔中, 因此含括 後即可在程式中呼叫它們。以下簡(jiǎn)介 中幾個(gè)函式的用法, 讓讀者有初步的認(rèn)識(shí), 至於其它函式的用法, 讀者可自行參考整合開(kāi)發(fā)環(huán)境的線上說(shuō)明。44字串長(zhǎng)度所謂字串長(zhǎng)度就是字串中所含的字元數(shù) (不含結(jié)束字元), 有時(shí)候程式要讓使用者輸入一些資料, 接著要檢查使用者輸入的字元數(shù), 就會(huì)用到可計(jì)算字串長(zhǎng)度的 strlen() 函式。呼叫此函式時(shí)需以字串 (字元陣列) 為參數(shù), 函式會(huì)傳回 unsign
17、ed int 型別的字元數(shù) (中文字會(huì)被視為 2 個(gè)字), 如範(fàn)例所示:45字串長(zhǎng)度46字串長(zhǎng)度1. 第 10 行用 cin 物件呼叫 getline() 函式, 此函式的功能是讓 cin 能取得一整行的輸入內(nèi)容, 便於我們輸入中間含空白字元的字串。因?yàn)橐?cin 預(yù)設(shè)的運(yùn)作方式, 在讀取輸入時(shí), 若遇到空白就會(huì)停止讀取, 所以若輸入如上例中的 Taipei City 時(shí), cin 只會(huì)讀到前半的 Taipei。2. 第 12、13 行分別輸出陣列的 sizeof() 運(yùn)算結(jié)果及呼叫 strlen() 查看字串長(zhǎng)度的結(jié)果。47字串長(zhǎng)度由輸出結(jié)果即可查覺(jué) sizeof() 和 strlen()
18、傳回值意義的不同, sizeof() 傳回的是變數(shù)的大小, 由於宣告 name 陣列時(shí)即宣告其可存放 80 個(gè)字元, 因此傳回 80 (位元組) 但 strlen() 則是計(jì)算字串的長(zhǎng)度, 也就是結(jié)束字元 0 之前有多少個(gè)字元, 所以即使 name 陣列足以容納 80 個(gè)字元, 但呼叫 strlen() 函式時(shí), 它所存放的字串 Taipei City 連空白只有 11 個(gè)字元, 所以 strlen() 傳回的數(shù)值為 11。48字串複製在處理變數(shù)時(shí), 我們可以用指定運(yùn)算子 (=), 把變數(shù) A 的值直接指定給變數(shù) B, 如 B=A。但陣列不能做這樣的操作, 所以我們也不能透過(guò)把 A 字串指定給
19、 B 字串的方式來(lái)作字串的複製。因此標(biāo)準(zhǔn)函式庫(kù)提供 2 個(gè)字串複製函式:49字串複製這 2 個(gè)函式都會(huì)傳回指向目的字串的指標(biāo), 其間的差別在於 strncpy() 可做局部的複製, 因此可用第 3 個(gè)參數(shù)指定要複製的字元數(shù)。其實(shí)參數(shù)中的目的字串、來(lái)源字串指的都是字元陣列, 由於來(lái)源與目的陣列的大小可能不同、來(lái)源陣列中的字串長(zhǎng)度不確定等因素, 在使用上述函式時(shí)要注意幾點(diǎn):1. 如果複製的字元數(shù)大於目的陣列的長(zhǎng)度時(shí), 可能會(huì)使超出的部份覆蓋到已被使用的記憶體, 而使程式出錯(cuò)。50字串複製2. 如果複製的字元數(shù)小於目的陣列的長(zhǎng)度, 則目的陣列中超出字串長(zhǎng)度的部份不會(huì)受影響。3. 用 strncpy(
20、) 複製含中文的字串時(shí), 要注意每個(gè)中文字要視為 2 個(gè)字元, 因?yàn)橹形淖执娣旁谧衷嚵袝r(shí), 每個(gè)字的編碼會(huì)佔(zhàn) 2 個(gè)元素的空間。因此要注意指定第 3 個(gè)參數(shù)時(shí), 若恰好是某個(gè)中文字的後半所在的位置, 將使該字元只複製一半的編碼, 導(dǎo)致目的字串出現(xiàn)奇怪的內(nèi)容。51字串複製所以, 如果要讓字串內(nèi)容正確地複製, 無(wú)論目的陣列內(nèi)是否已經(jīng)存有其它內(nèi)容, 其容量一定要足夠容納來(lái)源陣列中的字串。如以下程式中, 我們要將第 1 個(gè)字串內(nèi)容複製到第 2 個(gè)字串時(shí), 第 2 個(gè)字串的容量就比第 1 個(gè)字串大, 程式如下:52字串複製53字串複製54字串複製55字串複製程式共定義了三個(gè)含不同字串的字元陣列, 然後
21、將第 1 個(gè)字串分別用 strcpy() 及 strncpy() 複製給另 2 個(gè)字串, 並請(qǐng)使用者輸入複製局部字串時(shí), 要複製的字元數(shù)。56字串的比對(duì)陣列不僅無(wú)法用指定運(yùn)算子指定其值, 也無(wú)法使用比較運(yùn)算字來(lái)比較其內(nèi)容:57字串的比對(duì)上列的比較運(yùn)算式雖然合法, 但它們都不是在比較陣列的內(nèi)容, 而是在比較 2 個(gè)變數(shù)的位址, 因此這種比較基本上是沒(méi)什麼意義的。然而在字串應(yīng)用上免不了要做字串的比對(duì)及比較, 此時(shí)可使用下列 2 個(gè)函式:58字串的比對(duì)兩個(gè)函式都是傳回參數(shù)字串相減的數(shù)值, 也就是說(shuō), 函式會(huì)取兩字串的第一個(gè)字元相減, 如果差為 0 則繼續(xù)比較下一個(gè)字元, 直到差不為 0 時(shí), 便傳回
22、差值。所以, 傳回值可能有 3 個(gè)結(jié)果:59字串的比對(duì)strncmp() 的功能及用法也相似, 不過(guò) strncmp() 只會(huì)比較第 3 個(gè)參數(shù)所指定的前 n 個(gè)字元 (中文字同樣是視為 2 個(gè)字), 而不會(huì)比較到字串結(jié)束。這兩個(gè)函式的使用方式請(qǐng)參見(jiàn)以下範(fàn)例:60字串的比對(duì)61字串的比對(duì)62字串的比對(duì)程式請(qǐng)使用者輸入 2 個(gè)字串後, 即在第 15 行呼叫 strcmp() 函式比較兩個(gè)字串, 並比對(duì)傳回值是否為 0 (表示兩個(gè)字串相等), 輸出對(duì)應(yīng)的訊息。strncmp() 的用法也大致相同, 只不過(guò)需在第 3 個(gè)參數(shù)指定要比對(duì)的是前幾個(gè)字元, 在此就不多做介紹。637-3 多維陣列由多個(gè)陣列
23、組成的多維陣列二維陣列的初始值設(shè)定以陣列之陣列的形式設(shè)定初始值定義時(shí)省略維度值64由多個(gè)陣列組成的多維陣列如果把教室的一排座位看成是陣列, 每個(gè)位子上可坐一位同學(xué), 就好像每個(gè)元素可容納一筆資料, 若一排可坐 6 個(gè)人, 就是有 6 個(gè)元素的陣列。如果教室有多排座位, 譬如說(shuō)總共有 7 排, 這時(shí)我們可將它視為是有 7 個(gè)元素的陣列, 且這個(gè)陣列中的元素本身又是有 6 個(gè)元素的陣列, 此時(shí)我們稱這個(gè)陣列為二維陣列。65由多個(gè)陣列組成的多維陣列66由多個(gè)陣列組成的多維陣列二維陣列就是指元素的索引是有兩個(gè)維度。對(duì)一排座位 (一維陣列) 我們只需說(shuō)是第幾個(gè)位子, 即可指出座位 (元素) 的位置;對(duì)一
24、整間教 室 (二維陣列), 就必須指明是第幾列、第幾 行 (兩個(gè)維度), 才能明確指出座位 (元素) 的位置。若用 C+ 的語(yǔ)法來(lái)看, 就是在陣列名稱後要 用 2 個(gè)中括號(hào)來(lái)表示:67由多個(gè)陣列組成的多維陣列68由多個(gè)陣列組成的多維陣列以上就是宣告二維陣列的語(yǔ)法, 在這個(gè)陣列中總共有 n*m 個(gè)元素。二維陣列的其它性質(zhì)都和一維陣列類似, 例如元素索引都是從 0 開(kāi)始、指定元素時(shí)需指明 2 個(gè)中括號(hào)中的索引值等等。69由多個(gè)陣列組成的多維陣列同理, 若一層樓有 8 間教室, 我們又可將這 8 間教室視為一 有 8 個(gè)元素的陣列, 其中每個(gè)元素又是一個(gè)有 7 個(gè)元素 (每間教室有 7 排座位) 的
25、陣列, 而這個(gè)代表一層樓座位的陣列則稱為三維陣列;再進(jìn)一步推演, 若教學(xué)大樓有 4 層樓, 則每一樓又可以視為一個(gè)陣列元素, 組成另一個(gè)四維陣列。凡是維度超過(guò) 1 的陣列, 都通稱為多維陣列。70由多個(gè)陣列組成的多維陣列不過(guò)一般實(shí)用上很少使用超過(guò)二維的陣列, 因?yàn)橐粊?lái)操作不方便, 二來(lái)在寫(xiě)程式時(shí)也容易因混淆而出錯(cuò), 因此本節(jié)也只以二維陣列的應(yīng)用為主。其它多維陣列的應(yīng)用, 都可類推。71二維陣列的初始值設(shè)定二維陣列的宣告方式只是在變數(shù)名稱後多一組中括號(hào), 並不困難。但如果要定義其初始值, 由於二維陣列具有二個(gè)維度, 那初始值的設(shè)定順序是如何呢?72以陣列之陣列的形式設(shè)定初始值回顧一下前面提到的,
26、 我們可將多維陣列看成是由陣列組成的陣列, 所以在寫(xiě)初始值時(shí), 就可以用大括號(hào)中有大括號(hào)的方式將初始值分隔開(kāi)來(lái), 這樣就很容易分辨了。例如 a23 是兩個(gè)子陣列, 每個(gè)子陣列有 3 個(gè)元素, 所以可寫(xiě)成:73以陣列之陣列的形式設(shè)定初始值這樣寫(xiě)就很清楚了, 也不會(huì)弄混。當(dāng)然把內(nèi)層的大括號(hào)拿掉, 對(duì)程式也不會(huì)有任何影響, C+ 編譯器會(huì)依序先將初始值指定給 a0 x 的元素, 再指定給 a1x 的元素, 依此類推。同樣的, 若初始值數(shù)量不夠時(shí), 未指定的元素其初始值一律為 0。74以陣列之陣列的形式設(shè)定初始值75以陣列之陣列的形式設(shè)定初始值76以陣列之陣列的形式設(shè)定初始值1. 第 6 行定義可存放
27、 3 列、4 的二維陣列 iArray, 但只給了 6 個(gè)初始值。2. 第 8 行輸出以 sizeof() 運(yùn)算子取得的 iArray 陣列大小。由於整數(shù)資料型別佔(zhàn)用 4 個(gè)位元組, 因 此 4x3=12 個(gè)整數(shù)陣列元素即佔(zhàn)用 48 個(gè)位元組的記憶體空間。3. 第 1116 行利用巢狀的 for 迴圈依序輸出 iArray 各元素的值。第 11 行的 for 迴圈調(diào)整列的變化;第 12 行的迴圈則是做行的變化。77以陣列之陣列的形式設(shè)定初始值4. 第 16 行的敘述會(huì)在每輸出一列元素值後, 即換行輸出。讀者可看到, 二維陣列也可使用迴圈來(lái)操作、存取陣列元素, 只不過(guò)需使用巢狀迴圈才能遊歷整個(gè)陣
28、列中的所有元素。若維數(shù)愈大, 所需的巢狀迴圈也要愈多層。同樣的要在處理時(shí), 注意迴圈的條件運(yùn)算式內(nèi)容, 避免在操作時(shí)不小心超出陣列元素的索引範(fàn)圍。78定義時(shí)省略維度值在定義一維陣列時(shí), 可以省略方括號(hào)中的維度大小, 讓編譯器自動(dòng)依大括號(hào)內(nèi)的初始值數(shù)量來(lái)決定有幾個(gè)元素。定義二維陣列時(shí), 基本上也可以使用相同技巧, 但要注意的是, 為避免編譯器無(wú)法判斷各維度的大小, 所以只能省略最左邊的維度大小數(shù)值:797-4 指標(biāo)與參照除了陣列以外, C+ 還有兩種特別的資料類型, 稱為指標(biāo) (pointer) 與參照 (reference)。本節(jié)先來(lái)認(rèn)識(shí)指標(biāo)與參照, 及其與陣列的關(guān)係, 下一節(jié)則要介紹這兩種資
29、料型別在函式參數(shù)上的應(yīng)用。80宣告與使用指標(biāo)變數(shù)指標(biāo) (pointer) 也是一種變數(shù), 但是它所儲(chǔ)存的並非是變數(shù)的值, 而是記憶體中的一個(gè)位址, 例如某個(gè)變數(shù)實(shí)際存放在記憶體中的位址。當(dāng)指標(biāo)儲(chǔ)存一個(gè)位址時(shí), 我們稱此指標(biāo)指向該位址所表示的記憶體空間。81宣告與使用指標(biāo)變數(shù)何謂位址?我們可以把記憶體的儲(chǔ)存空間, 想像是一個(gè)一個(gè)排列整齊可用來(lái)裝填資料的小格子, 每個(gè)小格子的大小都相等 (1 位元組)而位址就是用來(lái)區(qū)別這些小格子, 也就是這些格子的代號(hào)。就好像車(chē)站中公用的儲(chǔ)物櫃, 每個(gè)小格子都有一個(gè)編號(hào)一樣, 由於這些編號(hào)有次序性, 所以透過(guò)編號(hào)就能找到櫃子的位置, 進(jìn)而取出放在櫃中的物件。82宣
30、告與使用指標(biāo)變數(shù)因此在 C+ 中的變數(shù), 就像是用來(lái)代替櫃子編號(hào)的名稱, 變數(shù)中存放的是我們要用到的資料;而指標(biāo)變數(shù)則是用來(lái)記錄櫃子號(hào)碼的變數(shù), 它所存放的是某筆資料所在的櫃子編號(hào), 而非資料本身。例如以下的示意圖:83宣告與使用指標(biāo)變數(shù)宣告指標(biāo)變數(shù)的方式很簡(jiǎn)單, 只需在變數(shù)名稱前加上一個(gè) * 符號(hào):1. 資料型別:指標(biāo)所指變數(shù)的型別, 必須與該指標(biāo)所指向的變數(shù)型別相同。2.*:稱為指位運(yùn)算子 (dereference operator), 而非乘法運(yùn)算子。在宣告變數(shù)時(shí), 用來(lái)表示變數(shù)為指標(biāo)變數(shù);若用在一般敘述中, 則表示要傳回指標(biāo)所指的變數(shù)值。3. 指標(biāo)變數(shù)名稱:這個(gè)變數(shù)的名稱。84宣告與使
31、用指標(biāo)變數(shù)宣告指標(biāo)變數(shù)後, 但要如何將其它變數(shù)的位址設(shè)給指標(biāo)變數(shù)?我們要如何知道變數(shù)存放在記憶體中的位址?很簡(jiǎn)單, 只要在變數(shù)名稱前加上取址運(yùn)算子 &, 就會(huì)傳回該變數(shù)的位址。比如說(shuō):85宣告與使用指標(biāo)變數(shù)如此一來(lái), ptr 便是指向 number 的指標(biāo)了。指標(biāo)是用來(lái)存取變數(shù)空間的位址, 所以不管指標(biāo)宣告成指向何種型別的變數(shù), 編譯器都是配置相同大小的空間給指標(biāo)變數(shù), 在目前一般個(gè)人電腦上, 指標(biāo)變數(shù)通常都是佔(zhàn)用 4 個(gè)位元組的空間 (在 64 位元系統(tǒng)並搭配 64 位元編譯器, 則指標(biāo)將佔(zhàn) 8 個(gè)位元組) 以下就是查看指標(biāo)變數(shù)各項(xiàng)資訊的範(fàn)例:86宣告與使用指標(biāo)變數(shù)87宣告與使用指標(biāo)變數(shù)88
32、宣告與使用指標(biāo)變數(shù)1. 第 6、7 行分別宣告整數(shù)變 數(shù) i 及倍精度浮點(diǎn)數(shù)變數(shù) d。2. 第 8 行定義指向整數(shù)變數(shù)的指標(biāo) iptr, 並用取址運(yùn)算子將 i 的位址設(shè)為其初始值。3. 第 9 行定義指向倍精度浮點(diǎn)數(shù)變數(shù)的指標(biāo) dptr, 並用取址運(yùn)算子將 d 的位址設(shè)為其初始值。4. 第 11、14 行分別用 sizeof() 運(yùn)算子顯示指標(biāo)變數(shù)的大小, 結(jié)果顯示一律為 4 位元組。89宣告與使用指標(biāo)變數(shù)5. 第 12、15 行直接輸出指標(biāo)變數(shù)的值, 也就是它們所指的位址值。cout 在輸出指標(biāo)變數(shù)時(shí), 預(yù)設(shè)會(huì)用 16 進(jìn)位的方式顯示。請(qǐng)注意, 設(shè)定指標(biāo)變數(shù)的值時(shí)需使用同型別的變數(shù)位址, 例
33、如以下的指定方式是錯(cuò)誤的:90存取指標(biāo)變數(shù)所指的值指標(biāo)變數(shù)存的是記憶體位址, 那我們要如何透過(guò)指標(biāo)來(lái)存取該位址的變數(shù)值?要透過(guò)指標(biāo)來(lái)存取變數(shù)值, 需使用指位運(yùn)算子 *, * 也稱為間接 (indirection) 運(yùn)算子, 意指透過(guò)指標(biāo)存取變數(shù)值時(shí), 是間接的存取, 不像用變數(shù)可直接存取到變數(shù)值。* 的用法是放在指標(biāo)變數(shù)名稱之前, 此時(shí)它就代表指標(biāo)所指位址中的資料, 例如:91存取指標(biāo)變數(shù)所指的值將指標(biāo)變數(shù)套上間接運(yùn)算子, 就相當(dāng)於存取指標(biāo)所指的變數(shù)一樣, 此時(shí)我們可以取得變數(shù)的值, 也可以更改其值。以下範(fàn)例示範(fàn)透過(guò)指標(biāo)存取變數(shù)值的情形:92存取指標(biāo)變數(shù)所指的值93存取指標(biāo)變數(shù)所指的值94存取
34、指標(biāo)變數(shù)所指的值使用指標(biāo)存取變數(shù)值時(shí), 也可以做轉(zhuǎn)型, 例如用整數(shù)指標(biāo)參與運(yùn)算, 但需得到含小數(shù)點(diǎn)的結(jié)果, 就可用以下方式:95指標(biāo)與陣列陣列與指標(biāo)有著密不可分的關(guān)係, 而陣列的 符號(hào)和指標(biāo)的 * 符號(hào)也有異曲同工之妙。指標(biāo)變數(shù)記錄著所指變數(shù)的記憶體位址, 而在程式中, 單寫(xiě)陣列名稱時(shí), 它也代表著陣列中第一個(gè)元素的位址。因此:96指標(biāo)與陣列由於陣列名稱本身所代表的意義, 就是該陣列的起始位址 (即第一個(gè)元素的位址), 所以在上例中我們可以將 a 指定給 p, 然後 p 便指向了 a 陣列中的第一個(gè)元素。當(dāng)然, 我們也可以用 &a0 來(lái)求得第一個(gè)陣列元素的位址, 而這個(gè)位址值和 a 的值是一樣
35、的 (均為陣列的起始位址)。97指標(biāo)與陣列更進(jìn)一步, 我們可以把指標(biāo)的值加上元素的索引值, 這時(shí)就等於由指標(biāo)存取陣列元素了:98指標(biāo)與陣列由這個(gè)例子可發(fā)現(xiàn), * 和 都是 依址取值 的意思, 而 中的編號(hào)就是依陣列位址 + 索引取值之意, 所以對(duì)應(yīng)到指標(biāo), 就變成指標(biāo) + 索引。我們甚至可以張冠李戴, 將 用於指標(biāo)之上, 而將 * 用於陣列名稱之上, 請(qǐng)參考以下的範(fàn)例:99指標(biāo)與陣列100指標(biāo)與陣列1. 第 8 行定義 ptr 字元指標(biāo)並將它指向 str 字元陣列。2. 第 10、11 行的迴圈將 str 當(dāng)成字元指標(biāo)使用, 並每次輸出 (str+i) 位址所存放的字元, 因此會(huì)輸出整個(gè) Ho
36、w are you? 字串的內(nèi)容。3. 第 14、15 行的迴圈則反其道而行, 將指標(biāo)變數(shù) ptr 當(dāng)成陣列名稱使用, 並從第 0 個(gè)元素開(kāi)始, 每次輸出第 i 個(gè)元素, 結(jié)果也是輸出整個(gè) How are you? 字串的內(nèi)容。101指標(biāo)與陣列將指標(biāo)的數(shù)值做加減時(shí), 就相當(dāng)於在對(duì)位址值做加減。但要特別注意一點(diǎn), 將指標(biāo)加減 1, 並不代表位址值加減 1, 而是索引值加減 1, 至於位址值則是加減 1 個(gè)指標(biāo)所指型別的大小。舉例來(lái)說(shuō), 在上例中, 指標(biāo)定義為 char 型別, 由 於 char 的大小是 1 個(gè)位元組, 所以對(duì)指標(biāo)做加減, 就是以 1 個(gè)位元組為單位做加減。然而若指標(biāo)為 int
37、型別, 則對(duì)指標(biāo)做加減時(shí), 一次是以 4 個(gè)位元組為單位做加減。其實(shí)只要將指標(biāo)加減法想成是陣列索引值增減就很容易瞭解, 我們?cè)儆靡韵鹿?fàn)例驗(yàn)證:102指標(biāo)與陣列103指標(biāo)與陣列104指標(biāo)與陣列如執(zhí)行結(jié)果所示, 將 int 指位器的值加 1 時(shí), 位址增加的值為 4, 符合 int 型別的大小, 如此才能指到下一個(gè)元素的位址並取得其值。因此程式中對(duì)指位器的運(yùn)算式 ptr + i, 實(shí)際上會(huì)變成如下的形式:105指標(biāo)與陣列雖然此處我們將指標(biāo)的位址做數(shù)值運(yùn)算, 但並不表示指標(biāo)可做所有類型的數(shù)值運(yùn)算, 例如位址乘位址、位址乘索引等都是無(wú)意義的計(jì)算?;旧现挥邢铝腥N指標(biāo) (位址) 的數(shù)值運(yùn)算是有意義的:
38、106字元陣列與指標(biāo)當(dāng)我們要定義一個(gè)二維的字元陣列來(lái)存放多個(gè)字串時(shí), 也可用一個(gè)指標(biāo)來(lái)指向它, 並透過(guò)指標(biāo)做相關(guān)的操作, 例如下個(gè)這個(gè)簡(jiǎn)單的例子:上例的 a 是一個(gè)二維陣列, 其內(nèi)部包含 3 個(gè)一維陣列:a0、a1 和 a 2, 而每個(gè)一維陣列又包含 4 個(gè)元素。如果我們直接操作 a0、a1 或 a2, 那麼它們就代表其個(gè)別一維陣列的起始位址:107字元陣列與指標(biāo)108字元陣列與指標(biāo)109字元陣列與指標(biāo)程式先宣告一個(gè)含 3 個(gè)字串的二維陣列, 接著將定義一個(gè)指向陣列的指標(biāo), 隨後操作該指標(biāo)輸出位址值做驗(yàn)證並顯示 3 個(gè)字串。請(qǐng)注意第 7 行的敘述, 我們定義的是 char (*str)4 而非
39、 char *str4, 這兩者的意義是不同的。由於 的運(yùn)算子的優(yōu)先順序高於 *, 所以第 2 種寫(xiě)法是宣告一個(gè)含 4 個(gè)元素的陣列, 每個(gè)元素是個(gè)字元指標(biāo), 所以可稱為指標(biāo)陣列 (指標(biāo)組成的陣列)至於我們?cè)诔淌街械膶?xiě)法, 110字元陣列與指標(biāo)因?yàn)閷?* 與變數(shù)名稱用括號(hào)括起來(lái), 而 4 的優(yōu)先順序在後, 所以 str 代表的是一個(gè)指標(biāo)變數(shù), 而它所指的則是一個(gè)含 4 個(gè)字元的陣列, 因此我們稱之為陣列指標(biāo) (指向陣列的指標(biāo))。由於 str 所指的是含 4 個(gè)字元的陣列, 表示它所指的型別大小為 4 個(gè)位元組, 所以我們將它加上索引值時(shí), 位址值每次都會(huì)加 4, 由執(zhí)行結(jié)果中即可驗(yàn)證。111可
40、節(jié)省儲(chǔ)存空間的指標(biāo)陣列指標(biāo)陣列是指構(gòu)成陣列的元素都是指標(biāo), 其定義或宣告的方式如下例:112可節(jié)省儲(chǔ)存空間的指標(biāo)陣列我們將每個(gè)陣列元素圖解如下:113可節(jié)省儲(chǔ)存空間的指標(biāo)陣列上面所定義的指標(biāo)陣列內(nèi)有 3 個(gè)元素, 每個(gè)元素都是指標(biāo), 然後我們便可將各指標(biāo)指向不同的字串。由 於 p 是一個(gè)陣列名稱, 所以 p 本身的值不可更改, 但其內(nèi)各元素的值則可以更改 (p0, p1, p2)。在定義指標(biāo)陣列時(shí)也可以給定初值, 而且 中的數(shù)目可以省略而交由編譯器去計(jì)算。例如:114動(dòng)態(tài)記憶體配置使用指標(biāo)時(shí), 並不是只能將指標(biāo)指向已宣告或定義的變數(shù), 我們也可用動(dòng)態(tài)記憶體配置 (dynamic memory
41、allocation) 的方式, 取得一塊記憶體空間給指標(biāo)使用, 讓指標(biāo)所指的是自己專用的空間。前面所學(xué)的變數(shù)及陣列, 經(jīng)過(guò)編譯器編譯後, 它們所能使用的記憶體空間就已固定, 不能變更。例如宣告了 10 個(gè)元素的整數(shù)陣列, 我們就只能用它來(lái)儲(chǔ)存 10 個(gè)整數(shù)資料, 不能儲(chǔ)存超過(guò)陣列容量的資料。115動(dòng)態(tài)記憶體配置而動(dòng)態(tài)記憶體配置則不同, 它是由程式在執(zhí)行過(guò)程中, 依當(dāng)時(shí)的實(shí)際需要臨時(shí)向作業(yè)系統(tǒng)要求一塊沒(méi)有被其他程式使用的記憶體空間, 而且要求的空間大小, 可以在執(zhí)行時(shí)才由程式?jīng)Q定。在程式執(zhí)行過(guò)程中, 若取得的記憶體已用不到了, 也可以隨時(shí)將之釋放 (release), 還給作業(yè)系統(tǒng), 讓作業(yè)系
42、統(tǒng)可將記憶體空間提供給其它有需要的程式使用, 如此可大幅的提高記憶體的使用效率。116new 運(yùn)算子要在程式中動(dòng)態(tài)配置一塊記憶體可使用 new 運(yùn)算子, 其語(yǔ)法如下:1. 資料型別:新配置空間的資料型別, 同時(shí)也決定配置空間的大小。例如指定為 int, 則會(huì)配置 4 個(gè)位元組的空間。2. 初始值:要設(shè)定的初始值, 可省略。117new 運(yùn)算子new 運(yùn)算子會(huì)傳回該新配置空間的記憶體位址, 因此我們可以把這個(gè)位址指定給指標(biāo)變數(shù), 讓指標(biāo)指向新配置的空間:118delete 運(yùn)算子由於可供程式使用的記憶體空間是有限的資源, 為免不必要的浪費(fèi), 我們應(yīng)在不再需要該空間時(shí), 將它釋放。要釋放由 new
43、 運(yùn)算子配置的空間, 可使用 delete 運(yùn)算子, 其語(yǔ)法就是在 delete 關(guān)鍵字後面接著指向該空間的指標(biāo)即可, 例如:119delete 運(yùn)算子上面的範(fàn)例, 是初始化動(dòng)態(tài)記憶體配置的寫(xiě)法, 也就是在宣告指標(biāo)的同時(shí), 便配置記憶體空間。配置成功後, 我們就取得了一個(gè)可存放整數(shù)型別的記憶體空間, 並可透過(guò) ip 指標(biāo)來(lái)存取這個(gè)空間??臻g使用完畢, 就 用 delete 將配置的記憶體釋放。120需要記憶體時(shí), 再配置我們也可以在宣告指標(biāo)時(shí)不做配置記憶體空間, 而是等到程式需要使用之前再配置空間。例如:121需要記憶體時(shí), 再配置不管是哪種配置方式, 記憶體空間使用完畢後, 一定要以 del
44、ete 將配置的記憶體空間釋放, 這是一個(gè)很重要的習(xí)慣, 可以讓記憶體的使用更具效率。122動(dòng)態(tài)配置陣列空間使用 new 運(yùn)算子也可以配置陣列的空間, 只要在型別的後面使用 並註明數(shù)量即可;而且以 delete 運(yùn)算子釋放陣列空間時(shí), 必須在 delete 後加上 符號(hào) (但不必註明數(shù)量):123動(dòng)態(tài)配置陣列空間以上第 1 行的 new 敘述就是配置 100 個(gè)整數(shù)的記憶體空間, 並將空間的起始位址指定給 array_ptr, 就相當(dāng)於建立一 個(gè) 100 個(gè) int 的陣列, 並將陣列起始位址指定給指標(biāo)。較特別的是, 在動(dòng)態(tài)配置陣列空間時(shí), 由於是在程式執(zhí)行到該敘述時(shí), 才配置所要的空間, 因
45、此可用變數(shù)來(lái)指定陣列大小, 而不像以非動(dòng)態(tài)的方式建立陣列只能使用常數(shù)或唯讀變數(shù)指定大小。124動(dòng)態(tài)配置陣列空間舉個(gè)例子來(lái)說(shuō), 要寫(xiě)一個(gè)程式來(lái)做不定個(gè)數(shù)值的計(jì)算??捎脛?dòng)態(tài)記憶體配置的方式, 在程式執(zhí)行時(shí)才決定要配置多少記憶體空間來(lái)使用, 如以下範(fàn)例所示:125動(dòng)態(tài)配置陣列空間126動(dòng)態(tài)配置陣列空間127動(dòng)態(tài)配置陣列空間128動(dòng)態(tài)配置陣列空間1. 第 11 行, 動(dòng)態(tài)配置記憶體空間, 配置空間型別 為 double, 配置空間為 sizeof (double)*how_many, how_many 為第 9 行中, 由鍵盤(pán)輸入的數(shù)值個(gè)數(shù)。2. 第 1316 行, 以 for 迴圈請(qǐng)使用者依序輸入所
46、有數(shù)值。3. 第 1921 行則計(jì)算並顯示所有數(shù)值的算數(shù)平均。4. 第 2426 行則計(jì)算並顯示所有數(shù)值的幾何平均。5. 第 28 行以 delete . 的語(yǔ)法釋放動(dòng)態(tài)配置的陣列空間。129動(dòng)態(tài)記憶體配置函式由於 C+ 沿用了所有的 C 語(yǔ)言標(biāo)準(zhǔn)函式庫(kù), 因此也可使用宣告於 的動(dòng)態(tài)記憶體管理函式:130一定要指定初始值的參考型別除了指標(biāo)變數(shù)外, 還有一種特殊型別的變數(shù)稱為參考型別 (Reference Type) 變數(shù), 參考型別變數(shù)的用處是讓我們?yōu)樽償?shù)或常數(shù)建立別名 (Alias), 然後便可用不同的識(shí)別字來(lái)參考到同一個(gè)資料或物件。參考型別的定義方式和指標(biāo)有點(diǎn)像, 但需改用取址運(yùn)算子 &
47、來(lái)定義或宣告, 例如:131一定要指定初始值的參考型別在定義參考型別的變數(shù)時(shí)一定要設(shè)定初值, 所以 int &j; 這樣的宣告是不合法的, 因?yàn)槿绱司幾g器就不能判斷它要作為誰(shuí)的別名。同一個(gè)變數(shù)可有多個(gè)別名, 這些別名的使用就和原來(lái)的變數(shù)完全一樣, 而且我們?cè)僖膊荒芨乃鼈冎g的參考關(guān)係了:132一定要指定初始值的參考型別以下範(fàn)例驗(yàn)證參考型別的行為:133一定要指定初始值的參考型別134一定要指定初始值的參考型別這個(gè)程式很簡(jiǎn)單, 只是將參考型別變數(shù) old 設(shè)為整數(shù)變數(shù) age 的別名, 之後則分別修改 age 及 old 的值, 並可由執(zhí)行結(jié)果發(fā)現(xiàn), 只要修改其中之一, 兩個(gè)變數(shù)的值都會(huì)一起更
48、改, 因?yàn)樗鼈兌际谴硗粋€(gè)記憶體空間 (同一個(gè)置物櫃)。參考型別主要是用在函式的參數(shù)傳遞和傳回值上。在其他情形下則應(yīng)避免使用, 因?yàn)樵谝话闱闆r下, 參考型別並不會(huì)帶來(lái)任何好處, 只是徒增困擾而已。1357-5 指標(biāo)與參考在函式上的應(yīng)用前面介紹了許多有關(guān)指標(biāo)與參考型別的基本用法, 但其實(shí)在一般的程式中會(huì)用到這些資料型別的情況, 有大半是因應(yīng)呼叫函式時(shí)要以特殊的方式傳遞參數(shù)時(shí)使用。那什麼是以特殊的方式傳遞參數(shù)呢?其實(shí)當(dāng)我們呼叫函式時(shí), 呼叫者 (例如 main() 函式) 傳遞參數(shù)給函式的方法共有 3 種:136指標(biāo)與參考在函式上的應(yīng)用傳值呼叫 (Call by Value):呼叫者會(huì)將參數(shù)的值
49、傳給函式中的參數(shù) (局部變數(shù)), 也就是只將數(shù)值複製過(guò)去。呼叫者呼叫函式時(shí)所用的參數(shù), 和函式中的參數(shù)是不同的變數(shù), 兩邊互不相干。當(dāng)函式修改參數(shù)值時(shí), 對(duì)呼叫者的變數(shù)並無(wú)影響, 這也是我們?cè)?第 6 章所學(xué)的參數(shù)傳遞方式。137指標(biāo)與參考在函式上的應(yīng)用傳址呼叫 (Call by Address):函式宣告的參數(shù)型別為指標(biāo)型別, 所以呼叫時(shí)需以變數(shù)的位址為參數(shù), 因此函式中的指標(biāo)參數(shù)會(huì)指向呼叫時(shí)所用的參數(shù)。傳參考呼叫 (Call by Reference):函式宣告的參數(shù)型別為參考型別, 所以函式中的參數(shù)會(huì)變成呼叫者呼叫時(shí)所用參數(shù)的別名。138傳址呼叫以一般的傳值呼叫, 函式無(wú)法修改視野只在呼
50、叫者中的變數(shù)。如果我們希望函式能直接存取呼叫者中的變數(shù), 就像存取自己視野中的變數(shù)一樣, 則可用傳址呼叫的方式來(lái)設(shè)計(jì)函式, 此時(shí)必須將函式的參數(shù)型別宣告成指標(biāo)型別:139傳址呼叫這樣一來(lái), 變數(shù) x 的位址會(huì)設(shè)給 func() 函式中的指標(biāo) i, y 變數(shù)的位址則會(huì)設(shè)給 j, 所以函式中可透這兩個(gè)指標(biāo), 直接存取到 main() 函式中的變數(shù) x、y, 甚至直接修改其值。例如要設(shè)計(jì)一個(gè)將 2 個(gè)變數(shù)值對(duì)調(diào)的函式, 就可用傳址呼叫的方式來(lái)設(shè)計(jì):140傳址呼叫141傳址呼叫142傳址呼叫143傳址呼叫如執(zhí)行結(jié)果所示, 在 main() 函式中將變數(shù)的位址傳遞到 swap() 函式中, 所以 swa
51、p() 函式中的 a、b 分別指向 main() 中的 a、b, 經(jīng)過(guò)函式交換數(shù)值的處理, 也相當(dāng)於將 main() 的局部變數(shù) a、b 的數(shù)值交換過(guò)來(lái)。除了上述需修改呼叫者數(shù)值的應(yīng)用, 還有一種情況也會(huì)用到傳址呼叫, 就是需傳遞整個(gè)陣列的情況。由於陣列名稱也可看成是指標(biāo), 所以要傳遞陣列時(shí), 可在函式中用陣列變數(shù)來(lái)接受參數(shù), 也可以用指標(biāo)變數(shù)來(lái)接受陣列的位址。144傳址呼叫例如以下程式片段就是將函式參數(shù)型別宣告為陣列, 呼叫函式時(shí)也以陣列為參數(shù)的用法:145傳址呼叫但要特別注意一點(diǎn), 由於傳遞陣列位址時(shí), 被呼叫的函式無(wú)法得知陣列的大小, 為避免函式操作指標(biāo)時(shí)超出陣列範(fàn)圍, 通常在設(shè)計(jì)這類函
52、式時(shí), 會(huì)加上另一個(gè)參數(shù)來(lái)傳遞陣列大小。146傳參考呼叫傳參考呼叫其實(shí)和傳址呼叫有些類似, 都是讓函式能直接存取呼叫者中的變數(shù)。要設(shè)計(jì)傳參考呼叫的函式, 須將函式的參數(shù)型別宣告成參考型別:147傳參考呼叫傳參考呼叫的方式和傳值呼叫相同, 只需以變數(shù)直接呼叫即可。但因?yàn)楹降膮?shù)為參考型別, 所以此時(shí)參數(shù)傳遞的方式就彷彿執(zhí)行以下敘述:這樣一來(lái), 函式中的 I、j 就變成 main() 函式中變數(shù) x、 y 的別名了, 所以在函式中存取 i、j, 就等於存取到 main() 函式中的變數(shù) x、y。例如前面的數(shù)值對(duì)調(diào)的函式, 可改用傳參考呼叫的方式設(shè)計(jì)成如下的形式:148傳參考呼叫149傳參考呼叫1
53、50傳參考呼叫151傳參考呼叫如執(zhí)行結(jié)果所示, 傳參考函式和傳址呼叫的函式有異曲同工之妙。那何時(shí)要採(cǎi)用傳參考函式?何時(shí)又要用傳址呼叫呢?我們可由參考型別和指標(biāo)的性質(zhì)來(lái)看:參考型別的變數(shù)一定要初始化, 也就是說(shuō)若要用傳參考呼叫, 參數(shù)必須是已經(jīng)存在的變數(shù) (或物件)但指標(biāo)可以是未指向任何空間的空指標(biāo) (null pointer), 所以只要函式能接受, 則傳遞空指標(biāo)給函式也無(wú)不可。152以指標(biāo)或參考型別為傳回值函式的傳回值型別也可以是指標(biāo)或參考型別, 以下先介紹傳回指標(biāo)的用法。傳回指標(biāo)傳回參考型別153傳回指標(biāo)由於 return 敘述只能傳回單一變數(shù), 若想傳回字串或陣列 (多個(gè)變數(shù)), 就需傳
54、回這個(gè)字串或陣列的起始位址, 讓呼叫者能以指標(biāo)變數(shù)來(lái)取得傳回的位址值。要傳回一個(gè)位址, 我們要將函式宣告成指標(biāo)型別, 例如:154傳回指標(biāo)如此一來(lái), 傳回值便為位址。舉個(gè)例子, 在標(biāo)準(zhǔn)函式庫(kù)中的字串處理函式, 有很多都是直接以指標(biāo)傳回處理過(guò)的字串, 讓呼叫者可直接使用, 這樣的設(shè)計(jì)有個(gè)好處, 就是若程式中要馬上用到該傳回結(jié)果, 可直接以函式表示之;不需再用一個(gè)變數(shù)去接受傳回值, 然後使用該變數(shù)。舉例來(lái)說(shuō), 要讓函式將某個(gè)字串中的小寫(xiě)全部轉(zhuǎn)成大寫(xiě), 然後將結(jié)果以另一個(gè)字串傳回, 這時(shí)就可用傳回指標(biāo)的方式處理:155傳回指標(biāo)156傳回指標(biāo)157傳回指標(biāo)1. 第 3 行含括標(biāo)準(zhǔn)函式庫(kù)中的 , 因?yàn)樯?/p>
55、後會(huì)用到其中的 toupper() 函式。2. 第 6 行將自訂函式的傳回值宣告為字元指標(biāo), 另外將參數(shù)型別宣告為 const 的意思, 是指函式中不會(huì)修改傳入的字串參數(shù)本身。3. 第 10 行即呼叫函式並立即用 cout 輸出傳回的字串內(nèi)容。158傳回指標(biāo)4. 第 1321 行即為自訂的字串轉(zhuǎn)大寫(xiě)函式, 第 15 行先用 strlen() 取得字串長(zhǎng)度, 再用 new 配置新的字串空間, 用以存放轉(zhuǎn)成大寫(xiě)的新字串。5. 第 17 行的 for 迴圈逐字將 ptr 所指字串中的每個(gè)字元, 用標(biāo)準(zhǔn)函式庫(kù)的 toupper() 函式 (其功能就是傳回參數(shù)字元的大寫(xiě)) 轉(zhuǎn)成大寫(xiě), 最後在第 20 行
56、用 return 傳回轉(zhuǎn)換結(jié)果。159傳回參考型別傳回參考型別的函式設(shè)計(jì)方式和傳回指標(biāo)的方式類似, 在此不多做介紹。但要提醒讀者, 要傳回參考型別或指標(biāo)時(shí), 要記得不要傳回局部變數(shù)的參考或指標(biāo), 否則函式結(jié)束時(shí)局部變數(shù)的生命期也結(jié)束, 呼叫者根本無(wú)法取得傳回值。160傳回參考型別其實(shí)我們已使用這一類型的函式很多次而不自知, 也就是標(biāo)準(zhǔn)輸出的 cout 物件的 運(yùn)算子。當(dāng)我們將一串字串和變數(shù)用 運(yùn)算子串在 cout 後面輸出時(shí)其實(shí) cout 變數(shù) 就是傳回 cout 物件的參考, 所以傳回值可繼續(xù)與下一 個(gè) 運(yùn)算子參與運(yùn)算。1617-6 綜合演練main() 函式的參數(shù)以陣列為參數(shù)的應(yīng)用:在陣列中搜尋資料傳遞二維陣列的應(yīng)用:字串排序162main() 函式的參數(shù)到目前為止, 我們所寫(xiě)的程式其 main() 函式都是沒(méi)有任何參數(shù)的, 但其實(shí) main() 函式也可以加上參數(shù)。mai
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 結(jié)構(gòu)優(yōu)化施工方案(3篇)
- 封線槽施工方案(3篇)
- 花紋鋁板施工方案(3篇)
- 2025年人力資源管理手冊(cè)
- 2025年高職(藥學(xué))藥物制劑技術(shù)基礎(chǔ)試題及答案
- 2025年大學(xué)(護(hù)理學(xué))老年康復(fù)護(hù)理學(xué)階段測(cè)試題及答案
- 2025年中職(汽車(chē)運(yùn)用與維修)發(fā)動(dòng)機(jī)故障診斷綜合測(cè)試卷及解析
- 2025年大學(xué)出版與發(fā)行(發(fā)行基礎(chǔ)理論)試題及答案
- 2025年高職第二學(xué)年(電力系統(tǒng)繼電保護(hù)技術(shù))繼電保護(hù)裝置調(diào)試專項(xiàng)測(cè)試卷
- 七年級(jí)化學(xué)(實(shí)驗(yàn)基礎(chǔ))2025-2026年下學(xué)期期末測(cè)試卷
- 監(jiān)理歸檔資料培訓(xùn)課件
- 七年級(jí)數(shù)學(xué)工程問(wèn)題單元試卷及答案
- 藥物不良事件課件
- 八年級(jí)語(yǔ)文上冊(cè)期末考點(diǎn)專題01 漢字書(shū)寫(xiě)與書(shū)法鑒賞(原卷版)
- 兒科專科建設(shè)與發(fā)展規(guī)劃指南
- 煤礦基本知識(shí)培訓(xùn)課件
- GB/T 9754-2025色漆和清漆20°、60°和85°光澤的測(cè)定
- 運(yùn)輸合同轉(zhuǎn)包協(xié)議書(shū)范本
- 回顧性研究設(shè)計(jì)及寫(xiě)作要點(diǎn)
- 中藥儲(chǔ)存養(yǎng)護(hù)管理制度
- T/CECS 10128-2021不銹鋼二次供水水箱
評(píng)論
0/150
提交評(píng)論