CH10 指標進階功能

Download Report

Transcript CH10 指標進階功能

第十章 指標進階功能

課前指引 字元陣列儲存的字串也可以儲存於指標中,稱為「字元指標」。字元 陣列雖然也是指標,但其為指標常數,宣告後就無法改變其位址,但 字元指標建立的字串,可以任意用指定運算子改變字串內容。在程式 中不確定的記憶體使用空間,或並非從頭到尾都要使用的記憶體,在 程式執行時再依實際需求配置適當的記憶體,當該記憶體不再使用時 就予以釋放,此種方式稱為「動態配置記憶體」

章節大綱

10-1 指標與字串

10-2 雙重指標與二維陣列

10-3 動態配置記憶體

10-4 命令列參數

備註:可依進度點選小節

10.1 指標與字串 在 C++ 中,字串事實上是由字元陣列組成, 陣列可由指標取代,而且執行效率更高。字 串也可以用指標表示,使用的彈性更大。 字元陣列的存取 字元陣列與一般數值陣列有很大不同,設計者使 用字元陣列時務必小心,否則極易產生錯誤結果 。一般數值陣列「顯示陣列名稱」或「顯示陣列 元素位址」時會顯示陣列起始位址或陣列元素位 址。

3

10.1 指標與字串 範例時間:讀取字元陣列字元值 詳細步驟,請翻閱課本10-3頁說明。 範例結果:

4

10.1 指標與字串 字元指標 字元陣列儲存的字串也可以儲存於指標中,稱為 「字元指標」。 字元指標最大的優點是其為指標變數,可以任意 改變其指向的記憶體位址。 宣告字元陣列後,系統就依字元陣列初始值配置 記憶體,字元陣列的值就不能再以指定運算子改 變其值,否則會產生錯誤。

5

10.1 指標與字串 字元指標 對於整數陣列使用「cout << 陣列名稱;」即可顯 示陣列起始位址,但對於字元陣列卻會顯示陣列 內容,就是顯示「note」。如果要顯示陣列起始 位址,需用「cout << (int *)陣列名稱;」才能 顯示位址,所以「cout << (int *)s;」會顯示 s 陣列起始位址。 如果要改變字元陣列的設定值需使用 strcpy 函 式,但因陣列的位址無法改變,當新值的內容變 大後,非常可能覆蓋記憶體中有用的內容,造成 不可預期的錯誤。

6

10.1 指標與字串 範例時間:覆蓋字元陣列 詳細步驟,請翻閱課本10-5頁說明。 範例結果:

7

10.1 指標與字串 圖示說明:

8

10.1 指標與字串 範例時間:字元指標改變陣列內容 詳細步驟,請翻閱課本10-7頁說明。 範例結果:

9

10.1 指標與字串 指標陣列 指標也與一般變數相同,可以宣告為陣列形態, 稱為「指標陣列」。指標陣列的宣告方式,是在 陣列名稱前加上星號「*」即可,其餘與一般陣列 相同,陣列中每一個元素都是指標。指標陣列的 宣告語法為: 資料型別 *陣列名稱[元素個數];

10

10.1 指標與字串 範例時間:字串陣列及指標陣列記憶體長度 詳細步驟,請翻閱課本10-10頁說明。 範例結果:

11

10.2 雙重指標與二維陣列 在二維陣列裡,由於有兩個索引數,如果要 使用指標的方式以兩個引數來存取各元素的 位址及設定值,必須使用雙重指標才能達成 。 雙重指標 指標變數的內容是變數的位址,但指標變數本身 也佔據記憶體空間,也擁有記憶體位址,如果另 一個指標變數的內容就是該指標變數的位址,即 另一個指標變數指向該指標變數,相當於「指標 的指標」,稱為「雙重指標」。雙重指標簡單的 說,就是「指向指標變數的指標變數」。

12

10.2 雙重指標與二維陣列 雙重指標 雙重指標的宣告方式是在變數名稱前面加上兩個 星號「**」,語法為: 資料型別 **變數名稱; 也可以在兩個括號之間加上括號: 資料型別 *(*變數名稱);

13

10.2 雙重指標與二維陣列 範例時間:顯示雙重指標位址及內容 詳細步驟,請翻閱課本10-12至10-13頁說明 。 範例結果:

14

10.2 雙重指標與二維陣列 範例雙重指標的示意圖:

15

10.2 雙重指標與二維陣列 二維陣列與指標 在一維陣列中,使用陣列名稱與指標變數存取陣 列元素,並沒有多大的差別,例如 int n[10] 的 整數陣列,可用陣列方式 n[i] 或陣列指標 *(n+i) 存取一維陣列元素。但在二維陣列裡,要 使用指標方式存取陣列元素必須使用雙重指標。

16

10.2 雙重指標與二維陣列 範例時間:顯示二維陣列元素位址及內容 詳細步驟,請翻閱課本10-15頁說明。 範例結果:

17

10.2 雙重指標與二維陣列 以指標存取二維陣列 使用指標方式存取二維陣列「陣列名稱[索引1][ 索引2]」中元素值的語法為: *(*(陣列名稱+索引1)+索引2); 整理指標方式與陣列方式存取二維整數陣列元素 值如下表:

18

10.2 雙重指標與二維陣列 範例時間:以指標存取二維整數陣列 詳細步驟,請翻閱課本10-17頁說明。 範例結果:

19

10.2 雙重指標與二維陣列 範例時間:尋找二維整數陣列最大值與最小 值 詳細步驟,請翻閱課本10-18至10-19頁說明 。 範例結果:

20

10.3 動態配置記憶體 靜態配置記憶體 程式中宣告的各種變數、陣列、指標等都會佔用 大小不等的記憶體,這些記憶體是在編譯時就由 系統配置,如此程式執行時就可使用,這種在編 譯時期就配置記憶體的方式,稱為「靜態配置記 憶體」。 靜態配置記憶體使用上較為方便,系統會自動配 置所需的記憶體,當程式結束後會自動收回記憶 體,也就是程式設計者完全不必操心記憶體分配 及回收問題,全部由系統處理。

21

10.3 動態配置記憶體 靜態配置記憶體 靜態配置記憶體最大問題是造成記憶體的浪費, 例如在程式中宣告的各種變數,由於編譯時就為 其預留了固定的記憶體,即使執行程式時並未使 用到這些記憶體空間,它們也不能被其他程式使 用。 又如宣告陣列時,常為設定陣列大小傷透腦筋, 如果宣告長度較大,使用上較不會出現問題,但 會浪費很多記憶體;若宣告長度較小,又怕執行 過程會有資料超過陣列大小而產生不可預期的錯 誤。

22

10.3 動態配置記憶體 靜態配置記憶體 另一個問題是指標的宣告,因為指標的內容是實 體變數的記憶體位址,若指標宣告後未明確指向 實體變數的記憶體位址,不可以將一個值放進未 取得實體變數位址的指標中。 動態配置變數 在程式中不確定的記憶體使用空間,或並非從頭 到尾都要使用的記憶體,在程式執行時再依實際 需求配置適當的記憶體,當該記憶體不再使用時 就予以釋放,此種方式稱為「動態配置記憶體」

23

10.3 動態配置記憶體 動態配置變數 使用動態配置記憶體最大的問題是,在結束程式 之前,程式設計者必須記得手動釋放取得的動態 配置記憶體,否則即使程式結束,該塊記憶體仍 會被佔用,其他程式將無法使用該塊記憶體,導 致記憶體不足。未被釋放的動態配置記憶體將一 直被佔用,直到關閉電腦為止。 要使用動態配置記憶體方式手動取得及刪除記憶 體,只要利用 new 及 delete 指令就能完成。

24

10.3 動態配置記憶體 動態配置變數 取得動態配置記憶體是使用 new 指令,為指標變 數建立動態配置記憶體的語法為: 資料型別 *指標變數 = new 資料型別; 建立動態配置記憶體時也可同時設定初始值,語 法為: 資料型別 *指標變數 = new 資料型別(初始值); 使用 delete 指令可釋放動態配置記憶體,語法 為: delete 指標變數;

25

10.3 動態配置記憶體 範例時間:動態配置記憶體方式計算乘積 詳細步驟,請翻閱課本10-23至10-24頁說明 。 範例結果:

26

10.3 動態配置記憶體 動態配置陣列 最適合使用動態配置記憶體的情況是陣列,因為 通常陣列所佔用的記憶體可能非常龐大,而在宣 告陣列時就必須指定陣列的長度,此長度是固定 的,一般會浪費大量記憶體。 若是使用動態配置記憶體方式,可在使用到陣列 時再依實際狀況給予最適當的陣列長度,使用後 立刻釋放記憶體,就能避免記憶體的浪費。 動態配置陣列與動態配置變數的使用方式雷同, 只要在 new 指令後方的資料型別加上中括號及元 素個數即可,語法為: 資料型別 *指標變數 = new 資料型別[元素個數];

27

10.3 動態配置記憶體 動態配置陣列 動態配置陣列也要使用 delete 指令釋放動態陣 列配置的記憶體空間,語法為: delete[] 指標變數; 範例時間:動態陣列轉換大小寫 詳細步驟,請翻閱課本10-25至10-26頁說明 。 範例結果:

28

10.4 命令列參數 若是以命令列執行程式,可以在程式名稱後 面加上需要的參數,做為傳送給程式的資料 ,此參數稱為「命令列參數」。 命令列執行程式所謂命令列執行程式就是在 MS-DOS 模式下輸入程式名稱執行程式。

29

10.4 命令列參數 以執行本章範例 twopoint.exe 執行為例, 操作過程如下(用 vista 系統做示範): 進入 MS-DOS 模式: 由桌面按 W 開始 \ 所 有程式 式 \ \ 附屬應用程 命令提示字元。

30

10.4 命令列參數 改變目錄至程式檔資料夾: 1.

輸入「 c: 」按 [Enter] 鍵,改變目錄至 C: 磁碟。 2.

3.

輸入「 cd \ 」後按 輸入「 cd DevCUnic\ch10 檔的資料夾。 [Enter] 鍵,改變目錄至 」後按 [Enter] C: 磁碟根目錄。 鍵,切換到至程式

31

10.4 命令列參數 執行程式顯示結果: 4. 輸入「 twopoint 」按 5.

顯示執行結果。 [Enter] 鍵執行程式。

32

10.4 命令列參數 main() 函式的參數 到目前為止所撰寫程式中的 main() 函式,都未 接收參數,事實上作業系統在呼叫主函式 main() 時也可以傳遞兩個參數,語法為: int main(int argc, char* argv[ ]) Argc:資料型別為整數,表示命令列參數的個數 。要注意此參數的傳回值包含程式名稱本身,所 以一定大於 0。 Argv:資料型別為字串指標陣列,傳送命令列中 輸入的資料,每個資料是以空白字元做為分隔, 每個資料的型別都是字串。

33

10.4 命令列參數 範例時間:顯示命令列參數資料 詳細步驟,請翻閱課本10-30頁說明。 範例結果:

34

10.4 命令列參數 範例時間:使用命令列參數計算總和 詳細步驟,請翻閱課本10-31至10-32頁說明 。 範例結果:

35

本章結束

Q&A討論時間

36