1 / 14

第八章 指標

第八章 指標. 8-1 指標 8-2 動態變數與陣列 8-3 綜合範例. 第八章 指標. 截至目前為止,我們介紹的資料型別有 2-3 節基本資料型別、第七章的陣列型別及結構型別,本章 8-1 節將介紹另一個進階資料型別,稱為指標 (Pointer) 。筆者也將在 8-2 節中說明如何使用指標及 malloc( ) 函式,以便在執行階段動態的配置記憶體。. 8-1 指標. 指標型別是所有高階語言所沒有的資料型別,它的優點是指標型別直接 與記憶體打交道,如此可以提升程式的執行效率。 指標型別的宣告

hertz
Download Presentation

第八章 指標

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第八章 指標 • 8-1 指標 • 8-2 動態變數與陣列 • 8-3 綜合範例

  2. 第八章 指標 截至目前為止,我們介紹的資料型別有2-3節基本資料型別、第七章的陣列型別及結構型別,本章8-1節將介紹另一個進階資料型別,稱為指標(Pointer)。筆者也將在8-2節中說明如何使用指標及malloc( )函式,以便在執行階段動態的配置記憶體。

  3. 8-1 指標 指標型別是所有高階語言所沒有的資料型別,它的優點是指標型別直接 與記憶體打交道,如此可以提升程式的執行效率。 指標型別的宣告 指標型別的宣告比較特殊,它必須藉助一種指標運算子(*),其宣告語 法如下: 資料型別 *指標變數; 資料型別可以是3-2節的基本資料型別,指標變數可以是一個合法的變數 名稱。例如,以下式子即宣告ptr是一個整數的指標變數。 int *ptr; 經過以上宣告之後,ptr即可指向任一整數變數位址,例如, int a=5; prt = &a;

  4. 則ptr指向整數a的位址,往後即可使用*ptr代表整數a。例如,以下敘述則ptr指向整數a的位址,往後即可使用*ptr代表整數a。例如,以下敘述 可印出*ptr的值。 printf (“%d”, *ptr); 若硬要印出ptr的值,如以下敘述: printf (“%d”, ptr); 則沒有意義了。因為ptr的值會隨著不同的機器與不同的執行次數而有不 同的值。所以,在指標型別中,我們並不在意ptr所在位址,在意的是*ptr 的值。

  5. 指標與一維陣列 接著我們要談如何使用指標型別存取陣列的值。例如,程式中若包含以 下的宣告: int *ptr; int a[5]={3, 8, 6, 2, 5}; ptr = a;     或 ptr = &a[0]; 則表示宣告ptr是一種指標型別,ptr本身是一個位址,*ptr才是一個值, 其中ptr=a的效果就是將ptr指向a[0]的位址,&符號是取址的意思。所以 若經以上設定, printf(“%d”, *ptr); 將可得3,若要得下一個陣列值,則應將指標向後移一個位置,例如: ptr++; /* ptr=ptr+1 */ printf(“%d”, *ptr); 或 printf(“%d”, ptr[1]); 均可得到結果8。其次,上式若只純粹取值,亦可以下式表示: printf(“%d”, *(ptr+1));

  6. 範例8-1a 同範例7-1c,但改用指標型別處理陣列的值。 範例8-1b 請以指標型別重做泡沫排序法。

  7. 指標與二維陣列 二維陣列在人們眼中通常用於處理二維的行列表格,但電腦內部的記憶 體中,是以一維的方式排列,所以雖然是二維的陣列,但在電腦記憶體 中已轉為一維的方式儲存,二維陣列以指標處理的步驟是先指定第一元 素給指標變數,如下所示: int *ptr, a[4][3]; ptr = &a[0][0]; /* 不能寫成ptr=a */ 其次,若要存取其值,只要使用陣列名稱與適當的位移即可。例如,以 下敘述可設定第i列第j行元素等於5。 *( *(a+i ) + j) =5; /* 不能寫成 * ( *ptr+i ) + j = 5 */ 上式若要以ptr表示,則應使用以下敘述將二維排列轉為一維的直線 列,其中3是第一維的行個數。 *( ptr + 3*i + j ) =5; /* 不能寫成 * ( a + 3*i + j ) = 5 */

  8. 以上敘述將二維的列與行轉為一維的直線排列,如下表所示,括號內為以上敘述將二維的列與行轉為一維的直線排列,如下表所示,括號內為 二維(列、行),括號外的為一維直線的位移量。 範例8-1c 請以指標重做範例7-1g的學生成績統計。

  9. 8-2 動態變數與陣列 變數與陣列除了可於設計階段佈置外,亦可於執行階段再產生,於設計 階段所佈置好的變數或陣列稱為靜態變數或陣列;於執行階段產生的, 則稱為動態變數或陣列。為什麼要有動態變數或陣列呢?那是因為有些情 況,於程式設計階段,並不知道要預留多大的陣列,若不管使用者所需 要的陣列大小為何,通通宣告一個最大值,則非常浪費記憶體,此時即 可使用本節所要介紹的動態變數與陣列。本節將介紹如何利用指標及簡 單的malloc( )函式,動態的取得程式執行時所需的記憶體。 • 動態變數及陣列使用步驟有三:宣告變數及陣列、動態產生變數及陣列、以及動態變數及陣列的存取,最後是釋放動態記憶體。分別說明如下:

  10. 宣告變數及陣列變數 動態陣列變數的宣告同一般陣列,如以下敘述可宣告一個edi變數,其型 別為int。 int * edi; 以下敘述,可宣告一個edi變數,其型別為pData。 pData * edi; pData型別定義如下: struct pData { char *name; int age; }; 以下敘述可宣告一個edi陣列變數,其型別為pData。 pData * edi[2]; 以下敘述可宣告一個edi的二維陣列,其型別為pData。 pData * edi[3][2];

  11. 動態產生變數及陣列 使用標頭檔<stdlib.h>中已宣告的malloc( )函式及free( )函式,於程式執 行時直接向記憶體要空間及釋放空間。 如果陣列有100個int,我們就必須明白的告訴記憶體100個int需要多少個 bytes,如下列程式片段所示: edi = malloc ( n * sizeof(int) ); /* n=100 */ 釋放記憶體 由於動態陣列是在程式執行時,直接向記憶體要求取得的,因此在程式 結束前,必須釋放出所取得的記憶體,如下所示。 free (edi); 存取動態陣列 動態陣列的使用與上節所介紹的指標存取相同,值得注意的是,動態向 記憶體要求取得的記憶體時並沒有進行初始化的動作,所配置到的記憶 體預設值不一定為0,因此在使用動態陣列時,要特別注意初始值的設 定。

  12. 範例8-2a 示範動態變數的用法。 範例8-2b 示範動態陣列的使用。本例於設計階段並不知使用者所要輸入的個數, 所以採用動態陣列逐一配置記憶體。 範例8-2c 示範動態一維陣列的產生及資料的存取。 範例8-2d 示範動態二維陣列的產生。 範例8-2e 示範兩個矩陣相加。

  13. 8-3 綜合範例 矩陣相乘 若有矩陣A23如下,我們稱為2列3行、記為A23,其中共有6個元素,每 個元素編號如下:   A23 = a11 a12 a13 a21 a22 a23 矩陣要能進行相乘,必須第一個矩陣的行數等於第二個矩陣的列數,且 相乘結果的列數要等於第一個矩陣的列數;結果的行數等於第二個矩陣 的行數。如下式為A矩陣乘以B矩陣的行列數目表示法。 Anm × Bmp = Cnp 其次,若有矩陣如下 : Cnp = Anm × Bmp 則任一子集合Cnp如下: m Cnp =  Ank × Bkp k=1

  14. 範例8-3 示範矩陣相乘。

More Related