Chapter 12 Pointers and Dynamic Arrays. Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 2 Overview Pointers (12.1) Dynamic Arrays.

Slides:



Advertisements
Similar presentations
1 生物計算期末作業 暨南大學資訊工程系 2003/05/13. 2 compare f1 f2  只比較兩個檔案 f1 與 f2 ,比完後將結果輸出。 compare directory  以兩兩比對的方式,比對一個目錄下所有檔案的相 似程度。  將相似度很高的檔案做成報表輸出,報表中至少要.
Advertisements

6-1 指標簡介 6-2 指標與陣列 6-3 動態配置記憶體 6-4 本章綜合練習
布林代數的應用--- 全及項(最小項)和全或項(最大項)展開式
Introduction to Java Programming Lecture 13 Classes I OO Programming.
第七章 抽樣與抽樣分配 蒐集統計資料最常見的方式是抽查。這 牽涉到兩個問題: 抽出的樣本是否具有代表性?是否能反應出母體的特徵?
學習C++的基本語法 認識關鍵字與識別字的不同 學習程式碼偵錯的流程 學習如何提高程式的可讀性
: A-Sequence 星級 : ★★☆☆☆ 題組: Online-judge.uva.es PROBLEM SET Volume CIX 題號: Problem D : A-Sequence 解題者:薛祖淵 解題日期: 2006 年 2 月 21 日 題意:一開始先輸入一個.
:Word Morphing ★★☆☆☆ 題組: Problem Set Archive with Online Judge 題號: 10508:word morphing 解題者:楊家豪 解題日期: 2006 年 5 月 21 日 題意: 第一行給你兩個正整數, 第一個代表下面會出現幾個字串,
3Com Switch 4500 切VLAN教學.
Reference, primitive, call by XXX 必也正名乎 誌謝 : 部份文字取於前輩 TAHO 的文章.
What is static?. Static? 靜態 ? class Test { static int staticX; int instanceX; public Test(int var1, int var2) { this.staticX = var1; this.instanceX =
Reference, primitive, call by XXX 必也正名乎 誌謝 : 部份文字取於前輩 TAHO 的文章 CS340100, NTHU Yoshi.
亂數產生器安全性評估 之統計測試 SEC HW7 姓名:翁玉芬 學號:
:New Land ★★★★☆ 題組: Problem Set Archive with Online Judge 題號: 11871: New Land 解題者:施博修 解題日期: 2011 年 6 月 8 日 題意:國王有一個懶兒子,為了勞動兒子,他想了一個 辦法,令他在某天早上開始走路,直到太陽下山前,靠.
: OPENING DOORS ? 題組: Problem Set Archive with Online Judge 題號: 10606: OPENING DOORS 解題者:侯沛彣 解題日期: 2006 年 6 月 11 日 題意: - 某間學校有 N 個學生,每個學生都有自己的衣物櫃.
: ShellSort ★★☆☆☆ 題組: Problem D 題號: 10152: ShellSort 解題者:林一帆 解題日期: 2006 年 4 月 10 日 題意:烏龜王國的烏龜總是一隻一隻疊在一起。唯一改變烏龜位置 的方法為:一隻烏龜爬出他原來的位置,然後往上爬到最上方。給 你一堆烏龜原來排列的順序,以及我們想要的烏龜的排列順序,你.
JAVA 程式設計與資料結構 第二章 JAVA 程式基本概念及操作. 第一個程式 /* * 這是第一個程式 (FirstP.java) */ class FirstP{ public static void main(String args[]){ System.out.println("Whatever.
STAT0_sampling Random Sampling  母體: Finite population & Infinity population  由一大小為 N 的有限母體中抽出一樣本數為 n 的樣 本,若每一樣本被抽出的機率是一樣的,這樣本稱 為隨機樣本 (random sample)
1. 假設以下的敘述為一未提供 “ 捷徑計算 ” 能力的程式段,試用程 式設計的技巧,使此敘述經此改 寫的動作後,具有與 “ 捷徑計算 ” 之 處理方法相同之處理模式。 if and then E1 else E2 endif.
例外處理. 內 容 大 綱 例外的產生 捕捉例外 丟出例外 例外的產生 (1/4) 一般常見的執行時期錯誤包括整數除法分母為 0(divide by zero) ,陣列索引值越限 (array index out of range) ,輸入輸出錯誤 (I/O error) 、檔案 不存在或無法存取.
MATLAB 程式設計 第 11 章 多維陣列 多維陣列的定義 在 MATLAB 的資料型態中,向量可視為 一維陣列,矩陣可視二維陣列,對於維 度 (Dimensions) 超過 1 的陣列則均可視 為「多維陣列」 (Multidimesional Arrays , 簡稱 N-D Arrays)
第 18 章 名稱空間與例外處理 18-1 名稱空間 18-1 名稱空間 18-2 例外處理 18-2 例外處理.
第三章 變數與繫結 陳維魁 博士 儒林圖書公司. 2 大綱  變數的定義  變數元件  儲存區配置問題  參考的透明性  完全計算  捷徑計算  繫結 (binding)  繫結時間  精選習題.
McGraw-Hill/Irwin © 2003 The McGraw-Hill Companies, Inc.,All Rights Reserved. 肆 資料分析與表達.
Monte Carlo Simulation Part.2 Metropolis Algorithm Dept. Phys. Tunghai Univ. Numerical Methods C. T. Shih.
Introduction to Java Programming Lecture 5: Using Java Classes : String & Math Spring 2009.
Chapter 13 塑模靜態觀點:物件圖 Static View : Object Diagram.
Introduction to Java Programming Lecture 17 Abstract Classes & Interfaces.
24-6 設定開始與結束場景中的 程式 最後我們要替這個遊戲收個尾, 幫它把開始 的等待畫面跟結束畫面處理一下。
: The largest Clique ★★★★☆ 題組: Contest Archive with Online Judge 題號: 11324: The largest Clique 解題者:李重儀 解題日期: 2008 年 11 月 24 日 題意: 簡單來說,給你一個 directed.
7 陣列與搜尋 7.1 陣列 一般資料變數 宣告一維陣列 起始一維陣列 7-4
Chapter 20 塑模動態觀點:狀態圖 Statechart Diagram. 學習目標  說明狀態圖的目的  定義狀態圖的基本記號  展示狀態圖的建構  定義活動、內部事件及遞延事件的狀態 圖記號.
: Happy Number ★ ? 題組: Problem Set Archive with Online Judge 題號: 10591: Happy Number 解題者:陳瀅文 解題日期: 2006 年 6 月 6 日 題意:判斷一個正整數 N 是否為 Happy Number.
: Fast and Easy Data Compressor ★★☆☆☆ 題組: Problem Set Archive with Online Judge 題號: 10043: Fast and Easy Data Compressor 解題者:葉貫中 解題日期: 2007 年 3.
CH 15- 元件可靠度之驗證  驗證方法  指數模式之可靠度驗證  韋式模式之可靠度驗證  對數常態模式之可靠度驗證  失效數為零時之可靠度估算  各種失效模式之應用.
: Multisets and Sequences ★★★★☆ 題組: Problem Set Archive with Online Judge 題號: 11023: Multisets and Sequences 解題者:葉貫中 解題日期: 2007 年 4 月 24 日 題意:在這個題目中,我們要定義.
:Nuts for nuts..Nuts for nuts.. ★★★★☆ 題組: Problem Set Archive with Online Judge 題號: 10944:Nuts for nuts.. 解題者:楊家豪 解題日期: 2006 年 2 月 題意: 給定兩個正整數 x,y.
資料結構實習-一 參數傳遞.
1 Introduction to Java Programming Lecture 2: Basics of Java Programming Spring 2008.
: Beautiful Numbers ★★★★☆ 題組: Problem Set Archive with Online Judge 題號: 11472: Beautiful Numbers 解題者:邱經達 解題日期: 2011 年 5 月 5 日 題意: 若一個 N 進位的數用到該.
Section 4.2 Probability Models 機率模式. 由實驗看機率 實驗前先列出所有可能的實驗結果。 – 擲銅板:正面或反面。 – 擲骰子: 1~6 點。 – 擲骰子兩顆: (1,1),(1,2),(1,3),… 等 36 種。 決定每一個可能的實驗結果發生機率。 – 實驗後所有的實驗結果整理得到。
函式 Function Part.2 東海大學物理系‧資訊教育 施奇廷. 遞迴( Recursion ) 函式可以「呼叫自己」,這種動作稱為 「遞迴」 此程式的執行結果相當於陷入無窮迴圈, 無法停止(只能按 Ctrl-C ) 這給我們一個暗示:函式的遞迴呼叫可以 達到部分迴圈的效果.
JAVA 程式設計與資料結構 第二十章 Searching. Sequential Searching Sequential Searching 是最簡單的一種搜尋法,此演 算法可應用在 Array 或是 Linked List 此等資料結構。 Sequential Searching 的 worst-case.
演算法 8-1 最大數及最小數找法 8-2 排序 8-3 二元搜尋法.
: Expect the Expected ★★★★☆ 題組: Contest Archive with Online Judge 題號: 11427: Expect the Expected 解題者:李重儀 解題日期: 2008 年 9 月 21 日 題意:玩一種遊戲 (a game.
845: Gas Station Numbers ★★★ 題組: Problem Set Archive with Online Judge 題號: 845: Gas Station Numbers. 解題者:張維珊 解題日期: 2006 年 2 月 題意: 將輸入的數字,經過重新排列組合或旋轉數字,得到比原先的數字大,
Learning Method in Multilingual Speech Recognition Author : Hui Lin, Li Deng, Jasha Droppo Professor: 陳嘉平 Reporter: 許峰閤.
Chapter 10 m-way 搜尋樹與B-Tree
: Function Overloading ★★★☆☆ 題組: Problem Set Archive with Online Judge 題號: 11032:Function Overloading 解題者:許智祺 解題日期: 2007 年 5 月 8 日 題意:判對輸入之數字是否為.
JAVA 程式設計與資料結構 第十六章 Hash Tables. Introduction Hash Tables 結構為一個 Array ,稱之為 Bucket array 。 如果想要新增一個物件,要根據這個物件的特性 將其加入 Hash Table 內。 Bucket Array 用 A 來代替,其.
1 Introduction to Java Programming Lecture 2: Basics of Java Programming Spring 2009.
5 重複迴圈 5.1 增減運算符號 增量運算符號 減量運算符號
第 6 章 迴圈結構 6-1 計數迴圈 6-1 計數迴圈 6-2 條件迴圈 6-2 條件迴圈 6-3 巢狀迴圈 6-3 巢狀迴圈 6-4 While/End While 迴圈 6-4 While/End While 迴圈 6-5 跳出迴圈 6-5 跳出迴圈 6-6 VB.NET 的錯誤處理 6-6 VB.NET.
Teacher : Ing-Jer Huang TA : Chien-Hung Chen 2015/6/30 Course Embedded Systems : Principles and Implementations Weekly Preview Question CH7.1~CH /12/26.
函式 Function 東海大學物理系‧資訊教育 施奇廷. 函式簡介 當程式越來越大、越複雜時,程式的維護、 除錯會變得更困難,此時必須引入函式來 簡化程式或將程式分段,將程式重複的部 分改寫為函式,將程式「模組化」 這種作法有下列優點:節省程式發展的時 間、邏輯容易瞭解、程式容易除錯、可分 工合作完成程式.
Visual C++重點複習.
1 Introduction to Java Programming Lecture 3 Mathematical Operators Spring 2008.
1 Introduction to Java Programming Lecture 2: Basics of Java Programming Spring 2010.
: SAM I AM ★★★★☆ 題組: Contest Archive with Online Judge 題號: 11419: SAM I AM 解題者:李重儀 解題日期: 2008 年 9 月 11 日 題意: 簡單的說,就是一個長方形的廟裡面有敵人,然 後可以橫的方向開砲或縱向開砲,每次開砲可以.
Microsoft Excel.
Introduction to Java Programming Lecture 16 Super and Sub Classes.
: Finding Paths in Grid ★★★★☆ 題組: Contest Archive with Online Judge 題號: 11486: Finding Paths in Grid 解題者:李重儀 解題日期: 2008 年 10 月 14 日 題意:給一個 7 個 column.
:Problem E.Stone Game ★★★☆☆ 題組: Problem Set Archive with Online Judge 題號: 10165: Problem E.Stone Game 解題者:李濟宇 解題日期: 2006 年 3 月 26 日 題意: Jack 與 Jim.
著作權所有 © 旗標出版股份有限公司 第 14 章 製作信封、標籤. 本章提要 製作單一信封 製作單一郵寄標籤.
幼兒行為觀察與記錄 第八章 事件取樣法.
1 Introduction to Java Programming Lecture 3 Mathematical Operators Spring 2009.
第 1 章 PC 的基本構造. 本章提要 PC 系統簡介 80x86 系列 CPU 及其暫存器群 記憶體: Memory 80x86 的分節式記憶體管理 80x86 的 I/O 結構 學習組合語言的基本工具.
: How many 0's? ★★★☆☆ 題組: Problem Set Archive with Online Judge 題號: 11038: How many 0’s? 解題者:楊鵬宇 解題日期: 2007 年 5 月 15 日 題意:寫下題目給的 m 與 n(m
McGraw-Hill/Irwin © 2003 The McGraw-Hill Companies, Inc.,All Rights Reserved. 肆 資料分析與表達.
Presentation transcript:

Chapter 12 Pointers and Dynamic Arrays

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 2 Overview Pointers (12.1) Dynamic Arrays (12.2) Classes and Dynamic Arrays(12.3)

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide Pointers ( 指標 ) 指標的內容是變數的記憶體地址 記憶體地址可拿來當做變數的名稱 假如一個變數需要 3 個記憶體空間 ( 一般是以 byte 為單 位 ), 則第 1 個記憶體空間的地址可當作該變數的名稱 當一個變數被用來當作 call-by-reference 的參數時, 其 實就是傳遞其記憶體地址

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 4 Pointers Tell Where To Find A Variable 指標就是用來告訴程式設計師某個變數在記憶體的 地址 指標透過地址告訴程式設計師一個變數儲放在哪裡,所 以說指標 指向 (“point” to) 一個變數

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 5 Declaring Pointers 指標變數必須宣告成含有 * Example: 下例宣告指向一個 double 變數的指標 : double *p; ‘*’ 標示變數 p 是一個指標

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 6 Multiple Pointer Declarations 要在一個宣告中宣告多個指標,在每個指標前加上 ‘*’ Example: int *p1, *p2, v1, v2; p1 and p2 指向 type int 的變數 v1 and v2 是 type int 的變數

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 7 The address of Operator ‘&’ 運算子可用來得到某變數之記憶體地址,該結 果可以給指向該變數資料型態的指標 Example: p1 = &v1; 執行後, p1 指向 v1 v1 也可以被稱為 “p1 指過去的變數 "

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 8 The Dereferencing Operator ( 提領:去 除記憶體地址 ) C++ 使用 ‘*’ 運算子處理指標的另一個做法 “p 指過去的變數 ” 在 C++ 中可以用 *p 表示 ‘*’ 在這種狀況就是 提領 (dereferencing) 運算子 p 在這種狀況就是被提領了 (dereferenced)

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 9 這列執行後, v1 及 *p1 為相同變數 A Pointer Example v1 = 0; p1 = &v1; *p1 = 42; cout << v1 << endl; cout << *p1 << endl; 輸出 : 42 42

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 10 Pointer Assignment 指定運算子 ( = ) 可用在指標上 Example: 如果 p1 指向 v1 ,則 p2 = p1; 會使 *p2, *p1, 及 v1 都是同一變數的不同名稱

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 11 Display 12.1 Caution! Pointer Assignments 使用指標變數來進行指定 (assignment) 時要特別 注意以下的不同 p1= p3; // 改變 p1 指向之記憶體地址 *p1 = *p3; // 改變 p1 指向之記憶體地址裡的值

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 12 The new Operator 使用指標時, 即使沒有變數名稱也能改變該指標指 向之記憶體裡的值 下例新增一個指向整數 (int) 之無名變數的指標 : p1 = new int; 這個變數可以用 *p1 來處理 ( 存取其值 ) *p1 可用於任何 integer 變數可以出現的地方 cin >> *p1; *p1 = *p1 + 7;

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 13 使用 new 運算子產生的變數叫做 動態變數 (dynamic variables) 動態變數 在程式執行時才會被新增其記憶體空間 或 送 回給作業系統 Display 12.2 有 pointers and dynamic variables 更多範例 Display 12.2 程式碼的解說在 Display 12.2 Display 12.3 Dynamic Variables

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 14 new and Class Types new 運算子用於類別 (class) 資料型態時會呼叫建構子 (constructor) 並配置記憶體給該物件 如果 MyType 是一個類別 class 資料型態, 則 MyType *myPtr; // 產生指向一個 MyType 物件 // 的指標 myPtr = new MyType; // 呼叫 MyType 預設建構子 myPtr = new MyType (32.0, 17); // 呼叫 Mytype(double, int) 建構子

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 15 Basic Memory Management 記憶體中有一塊區域叫做自由儲存區 ( the freestore ) ,表示尚未配置給任何變數的記憶體區 域,預留給在程式執行時所新增的動態變數 新增的動態變數會使用 freestore 的記憶體 如果 freestore 全部被用光了, new 的呼叫就會失敗 不再需要的動態變數所佔用之記憶體可以回收至 freestore 當程式不再使用一個變數時, 該變數可被 delete 掉, 該 變數所使用的記憶體就會回到 freestore

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 16 The delete Operator 當程式不再需要一個變數時, 可以刪除 (delete) 他 以將記憶體回收至 freestore Example: delete p; 執行後, p 的值 ( 記憶體地址 ) 就是未定義 (undefined) , 且原來 p 所指向之記憶體就回收至 freestore

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 17 Dangling Pointers 使用 delete 於一指標變數 摧毀掉該變數所指向之 動態變數 如有另一指標變數指向該動態變數, 則該指標變數 也會變成未定義 (undefined) 未定義之指標變數也叫做 dangling pointers ( 晃蕩 指標 ) 提領 (dereference) 一個 dangling pointer (*p) 通常會使 程式當掉

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 18 Automatic Variables 函式中宣告的變數所需的記憶體空間,通常在執行 到該函式時會被新增,當程式離開該函式時,該函 式所新增的記憶體空間會被回收 這些可稱為自動變數, 因為他們的新增與回收是由執行 程式自動控制 程式設計師必須運用 new 及 delete 手動控制指標 變數的新增及回收

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 19 Global Variables 在所有函式外面宣告之變數被稱為全域變數 全域變數可在程式任何地方使用 ( 包括在函式內 ) 全域變數一般很少用

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 20 Type Definitions 一個名稱可以用來定義新的資料型態, 該名稱之後 就能用來宣告變數 關鍵字 typedef 就是用來定義新的資料型態的名稱 語法 : typedef Known_Type_Definition New_Type_Name; Known_Type_Definition 可以是任何資料型態

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 21 Defining Pointer Types 為避免使用指標時的錯誤, 可以定義一個指標資料 型態 Example: typedef int* IntPtr; 定義一個新的資料型態, IntPtr, 給指向 int 變數的指標 之後, 以下兩個宣告有相同意義 IntPtr p; int *p;

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 22 Multiple Declarations Again 使用以下的新資料型態 IntPtr : typedef int* IntPtr; 可避免宣告兩指標變數時,犯了以下的宣告錯誤 : int *P1, P2; // 只有 P1 是指標變數, P2 不是 // 指標變數 改用以下宣告 IntPtr P1, P2; // P1 and P2 都是指標變數

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 23 Pointer Reference Parameters 使用 typedef 的第 2 個好處是在函數的參數定義 Example: void sample_function(IntPtr& pointer_var); 比下例清楚 void sample_function( int*& pointer_var);

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 24 Section 12.1 Conclusion Can you Declare a pointer variable? Assign a value to a pointer variable? Use the new operator to create a new variable in the freestore? Write a definition for a type called NumberPtr to be a type for pointers to dynamic variables of type int? Use the NumberPtr type to declare a pointer variable called my_point?

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide Dynamic Arrays 動態陣列指陣列的大小必須於程式執行時才知道, 無法於程式設計時就知道其大小。

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 26 Pointer Variables and Array Variables 陣列變數其實就是指向陣列第一個元素的指標變數 Example: int a[10]; typedef int* IntPtr; IntPtr p; a and p 為相同種類之變數 因為 a 是指向 a[0] 的指標變數 p = a; 會使 p 與 a 指向相同的變數 ( a[0] )

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 27 Display 12.4 Pointer Variables As Array Variables 反方向來說,指標變數也可以當陣列變數來使用 Example: p[0], p[1], …p[9] 都符合 C++ 的語法 變數 a 可以當作指標來使用,但是 a 的指標值 ( 即其記憶體地址 ) 不能被異動 以下不符合 C++ 的語法 : IntPtr p2; … // p2 is assigned a value a = p2 // attempt to change a

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 28 Creating Dynamic Arrays 一般陣列的大小在程式設計師寫程式時就知道 但假設程式設計師預估的值太大 ? 程式執行時浪費記憶體 但假設程式設計師預估的值太小 ? 某些狀況下,程式可能無法執行 動態陣列就是要在程式執行時給程式剛好大小的陣 列,不會太大,也不會太小

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 29 動態陣列是用 new 運算子產生 Example: 下例產生一個含 10 個 double 元素之動 態陣列 : typedef double* DoublePtr; DoublePtr d; d = new double[10]; 這樣 d 就可以如一般陣列一樣使用 ! 這可以是一個 integer 變數 ! Creating Dynamic Arrays

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 30 ( 接上頁 ) d 這個指標變數指向 d[0] 當程式不再需要這個陣列, 這個陣列應該要回收至 freestore Example: delete [ ] d; 中括號 [ ] 告訴 C++ 一個動態陣列要被回收刪除了,因此 C++ 會檢查此動態陣列的大小以了解應該要回收多少個元素 如果忘了加上 [ ] ,仍然為合法的 C++ 語法,但 C++ 會只回收 陣列第 1 個元素 Display 12.5 (1) Display 12.5 (2) Dynamic Arrays (cont.)

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 31 Pointer Arithmetic 陣列所代表的記憶體地址可以執行加減運算 以 double 動態陣列, d, 為例, 再提醒一次 d 指向 d[0] 運算式 d+1 為 d[1] 的地址, d+2 為 d[2] 的地址 注意加 指標 +1 會讓 指標加上該變數所需之記憶體的大小

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 32 Pointer Arithmetic Operations 指標的加加減減 ++ and - - 運算子可用於指標 相同資料型態的兩個變數的指標可以拿來相減,可以得 到這兩個指標間的元素個數 注意此兩個變數必須在同一陣列 下例顯示指標的加減 : for (int i = 0; i < array_size; i++) cout << *(d + i) << “ ” ; // 與 cout << d[i] << “ ” ; 同樣的意思

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 33 Multidimensional Dynamic Arrays 以下為產生一個 3x4 二維整數動態陣列 ( 相同方法 可擴充至更高維動態陣列 ) 的注意事項 視多維動態陣列 為 以陣列為基底 的陣列 ( 上層 ) 首先產生一個 “ 基底為整數指標 ” 之一維動態陣列 先定義 整數指標 的新資料型態 : typedef int* IntArrayPtr; 再定義其動態陣列 m: IntArrayPtr *m = new IntArrayPtr[3]; ( 底層 ) 其次,對 m 中的每一個指標, 產生一個整數的動 態陣列 for (int i = 0; i<3; i++) m[i] = new int[4];

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 34 m IntArrayPtr's int's IntArrayPtr * A Multidimensional Dynamic Array 上頁的二維動態陣列圖示如下 :

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 35 刪除多維動態陣列的方法 ( 先回收底層,再回收上 層 ) 每一個呼叫 new 所產生的動態陣列都需要一個對應的 delete[ ] 呼叫 Example: 以下刪除上頁之二維動態陣列 : for ( i = 0; i < 3; i++) delete [ ] m[i]; // 先刪除底層的整數動態陣列 delete [ ] m; // 再刪除 IntArrayPtr 動態陣列 Display 12.6 (1)Display 12.6 (2) Deleting Multidimensional Arrays

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 36 Section 12.2 Conclusion Can you Write a definition for pointer variables that will be used to point to dynamic arrays? The array elements are of type char. Call the type CharArray. Write code to fill array "entry" with 10 numbers typed at the keyboard? int * entry; entry = new int[10];

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide Classes and Dynamic Arrays 動態陣列的基礎資料型態可以是類別 如 Watch *p; X=10; p = new Watch[x]; 一個類別可以有 動態陣列的 成員變數 StringVar 就是一個範例.

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 38 Program Example: A String Variable Class 我們將定義 StringVar 類別 StringVar 物件是用來代表字串 StringVar 物件使用字元動態陣列,其大小必須在執行 程式時才知道 StringVar 類別與 11-2 的 string 類別功能相似

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 39 The StringVar Constructors StringVar 預設建構子 產生一個代表空字串的 StringVar 物件,此字串最大長度設為 100 ( 註: 因為此字串可能變長,因此需預留空間 ) StringVar 第 2 個建構子需要一個 int 的參數,來 決定此空字串物件以後之最大長度值 StringVar 第 3 個建構子需要一個 C-string 的參數以 … 將該 C-string 的長度設為此字串之可能最大長度 將該 C-string 複製到此字串之內部動態陣列變數上

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 40 Display 12.7 (1)Display 12.7 (2) The StringVar Interface 除了建構子, StringVar 的介面包括 : 成員函式 : int length( ); void input_line(istream& ins); friend ostream& operator << (ostream& outs, const StringVar& the_string); Copy 建構子 …( 晚點再討論 ) Destructor 解構子 …( 晚點再討論 )

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 41 Display 12.8 A StringVar Sample Program 使用 StringVar 在 Display 12.7 的介面 我們可以寫一使用 StringVar 類別之程式 此程式內的 conversation 函式可以: 產生 2 個 StringVar 物件, your_name 及 our_name your_name 的字串最長可達 max_name_size our_name 初始值為 “Borg” ,只能改變為不大於 4 個字元的字串

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 42 Display 12.9 (1) Display 12.9 (2) The StringVar Implementation StringVar 使用一個字元動態陣列來存放代表該字 串的字元們 StringVar 建構子呼叫 new 為成員變數 value 產生動態 字元陣列 value 要用 ‘\0’ ( 虛字元 ) 來中止字串 ( 請參考 11-1) 此陣列之大小必須等到程式執行 new 時才會知道 建構子的參數 ( 不論是 預設建構子、一個整數參數之建構子、 一個字串參數之建構子 中任一個 ) 會決定其大小

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 43 Dynamic Variables 只有呼叫 delete 運算子,動態變數 ( 及陣列 ) 才能回 收 即使一個區域指標變數在函式結束後自動回收, 該指標 所指向的動態變數 ( 及陣列 ) 會留在程式中,除非呼叫 delete 將其回收 但是使用 SringVar 類別的程式設計師不可能知道 StringVar 是用了一動態陣列作為其私有成員變數,所 以當程式不再需要一個 StringVar 物件時,不會也不能 呼叫 delete 來回收動態陣列

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 44 Destructors 解構子是一個成員函數,當該類別的物件離開其有 效範圍時 ( 如函式結束時、 for 迴圈結束時等等 ) , 解構子會被自動呼叫 解構子必須含有將建構子產生的動態陣列回收的程式碼 一個類別僅需要一個不用任何參數的解構子 解構子的宣告就是在預設建構子前加上 ~ Example: ~StringVar( );

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 45 ~StringVar StringVar 的解構子必須呼叫 delete [ ] 來回收動態陣列的記憶體空間至自由儲 存區 (the freestore) Example: StringVar::~StringVar( ) { delete [ ] value; }

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 46 Display 12.10Display Pointers as Call-by-Value Parameters 在函式呼叫時,將指標 (pointers) 作為 call-by- value 的參數會產生沒有預期到的結果 記得參數 (parameters) 是函式的區域變數 在函式內改變參數 (parameter) 的值,不會造成引數 (argument 即呼叫函式的變數 ) 的值跟著改變 參數的值設為引數 (argument) 的值,當引數為指標時其 值為一記憶體地址 因此參數及引數有相同之值 ( 即指標指向之記憶體之地址 ) 如果參數用來改變其地址指向之記憶體內容, 因為引數指 向之記憶體即為參數指向之記憶體,因此引數指向之記 憶體內容也改變了,如 Display 12.10, 所示

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 47 Copy Constructors 如果不想造成上頁的副作用 ( 即用指標變數做引數 呼叫 call-by-value 的函式參數,可以改變此指標 變數指向的變數的值 ) ,可用 複製 (copy) 建構子 幫忙解決 複製建構子的參數之資料型態即為該類別 此參數必須為 call-by-reference 此參數通常是一個 constant 參數, ( 不改變引數物件的 內容 ) 此建構子產生一個完整且獨立的引數複製物件,讓引數 物件與該新生物件不會糾纏在一起

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 48 StringVar Copy Constructor StringVar 之複製建構子程式碼如下: 產生一個新的動態陣列準備來放字串的字元 將引數的字串 ( 即動態字元陣列 ) 複製到此物件剛產生的 動態字元陣列 StringVar::StringVar(const StringVar& string_object) : max_length(string_object.length() ) { value = new char[max_length+ 1]; strcpy(value, string_object.value); }

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 49 Calling a Copy Constructor 在宣告該類別的物件時,複製建構子與其他建構子 的呼叫方式相同 複製建構子在以下狀況會被自動呼叫 宣告時,當其引數為相同類別的物件 當一個函式傳回一個該類別的值 ( 即物件 ) 當一個 call-by-value 參數以該類別的物件作為引數呼叫

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 50 The Need For a Copy Constructor 假設沒有複製建構子,下例顯示在引數呼叫時,會 有什麼問題 void show_string(StringVar the_string) { …} StringVar greeting("Hello"); show_string(greeting); cout << greeting << endl; 當呼叫 show_string(greeting) 時, greeting 被複製到參 數 the_string the_string.value 被設為與 greeting.value 相同

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 51 greeting.value the_string.value "Hello" The Need For a Copy Constructor (cont.) 因為 greeting.value 及 the_string.value 都是指標, 他們指向同一動態陣列

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 52 greeting.value the_string.value Undefined The Need For a Copy Constructor (cont.) 當 show_string 執行結束時, the_string 的解構子會自動被 執行, 將 the_string.value 指向之動態陣列回收至自由儲存 區 ( the freestore) 這時 greeting.value 指向的記憶體已經被回收至自由儲存 區 ( the freestore)

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 53 The Need For a Copy Constructor (cont.) Greeting 這個 StringVar 物件有 2 個問題 輸出 greeting.value 很可能會出現錯誤 有時 OK ,但不能靠運氣 當離開 greeting 的有效範圍時, 他的解構子會自動被呼叫 同一記憶體地址被解構子呼叫回收 2 次會造成系統錯誤 (system crashing error)

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 54 greeting.valuethe_string.value "Hello" Copy Constructor Demonstration 當有了複製建構子,上面的問題就不會發生了 greeting.value 及 the_string.value 指向記憶體不同位置

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 55 greeting.valuethe_string.value "Hello" undefined Copy Constructor Demonstration (cont.) 當 the_string 離開有效範圍 ( 即函式結束 ), StringVar 的解構子會被呼叫, 將 the_string.value 回收至自由儲存區 (the freestore ) greeting.value 仍然還在,可以被存取、被回收

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 56 When To Include a Copy Constructor 當一個類別的定義 ( 即實做 ) 需用到指標及 new 來 動態配置記憶體, 就需要複製建構子 當一個類別的定義沒有用到指標及 new 來動態配 置記憶體, 就不需要複製建構子

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 57 The Big Three 大三元包括 複製建構子 指定運算元 ( 下頁說明 ) 解構子 如果需要定義其中一個, 三個就都需要定義

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 58 The Assignment Operator 給定以下宣告 : StringVar string(10), string2(20); 這個程式碼 string1 = string2; 是合法的語法 但是, 因為 StringVar‘s 的成員變數 value 是一個指 標, 我們會將 string1.value 及 string2.value 指向同一記憶體位置 會使得前面討論複製建構子所提的問題又再重現

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 59 Overloading = 解決之道就是覆蓋 ( overload ) 指定運算子 ( = ) ,讓 StringVar 的指定不致產生問題 = 運算子是以成員函式 (member function) 來定義 Example: operator = declaration void operator=(const StringVar& right_side); right_side 是 = 運算子右邊的引數

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 60 Definition of = StringVar 的 = 運算子的實做之一 : void StringVar::operator= (const StringVar& right_side) { int new_length = strlen(right_side.value); if (( new_length) > max_length) new_length = max_length; for(int i = 0; i < new_length; i++) value[i] = right_side.value[i]; value[new_length] = '\0'; }

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 61 = Details 這個 StringVar = 的版本的作法是 比較 = 左右兩個 StringVar 物件的長度 最多只改變左邊 StringVar 物件可允許的最大長度 會將右邊物件的字串內容複製到左邊物件,而且彼此獨 立不會互相影響

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 62 Problems with = 這個 = 的實做的問題 通常我們不會去管右邊物件的字串內容大小,我們希望 要一個右邊物件的完整複製品 要完成以上要求, 我們需要先回收左邊物件的動態陣列, 然後配置夠大的動態陣列來容納右邊物件的字串內容 下頁顯示採用以上方法的一個嘗試,但這是一個有問題 (buggy) 的 = 運算子實做

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 63 Another Attempt at = void StringVar::operator= (const StringVar& right_side) { delete [ ] value; int new_length = strlen(right_side.value); max_length = new_length; value = new char[max_length + 1]; for(int i = 0; i < new_length; i++) value[i] = right_side.value[i]; value[new_length] = '\0'; }

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 64 A New Problem With = 上頁的 = 運算子實做的問題 如果有人無聊到將 = 的左右兩邊設為相同物件的話 my_string = my_string; 上頁的 = 運算子實做先回收左方物件的動態字元陣列. 由於左右兩邊為相同物件, 右方的動態字元陣列也被回 收了,沒有辦法執行 strlen(right_side.value) ,也無法 利用 right_side.value[i] 得到原來的各個字元

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 65 A Better = Operator void StringVar::operator = (const StringVar& right_side) { int new_length = strlen(right_side.value); if (new_length > max_length)// 只有需要更多空間 { // 時才回收 delete [ ] value; max_length = new_length; value = new char[max_length + 1]; } for (int I = 0; i< new_length; i++) value[i] = right_side.value[i]; value[new_length] = '\0'; }

Copyright © 2005 Pearson Addison-Wesley. All rights reserved. Slide 66 Section 12.3 Conclusion Can you Explain why an overloaded assignment operator is not needed when the only data consist of built-in types? Explain what a destructor does? Explain when a copy constructor is called?