SlideShare a Scribd company logo
1 of 118
第8章 指標


認識指標
指標與陣列的應用
動態配置記憶體
上機實習課程
8-1 認識指標
認識指標(1)

 指標與記憶體有著相當密切的關係。
 現在請您思考一個問題,變數是用來儲存數值,
  而數值究竟儲存在記憶體中的哪個位址上呢?
   相當簡單,如果要了解變數所在記憶體位址,
    只要透過 &(取址運算子)就能求出變數所在
    的位址。語法格式如下:


    &變數名稱;

                                2
認識指標(2)             8-1 認識指標



   程式範例:&(取址運算子)的宣告與使用範例:
    CH08_01.c




                               3
8-1 認識指標




   執行結果




   程式解說
    第6~8行分別宣告三種不同型態的變數,第10~12行則
    以%p格式來表示16進位的位址,如果要取出變數的位
    址只要在變數前加上&運算子即可。                4
8-1 認識指標
指標變數的宣告(1)

   指標的宣告方式如下:

    資料型態 *指標名稱;
    或
    資料型態* 指標名稱;


   以下是幾個指標變數的宣告方式:

    int* x;
    int *x, *y;
                                 5
8-1 認識指標




 在宣告指標時,我們可以將*置放於型態宣告
  的關鍵字旁,或是變數名稱旁邊,通常若要宣
  告兩個以上的變數,會將*靠在變數名稱旁,
  增加可讀性。
 當然指標變數宣告時也可設定初值為0或是
  NULL來增加可讀性:

    int *x=0;
    int *y=NULL;


                              6
8-1 認識指標



 以下程式是很經典的指標範例,主要是說明指
  標變數address1的儲存內容是位址,
  *address1則是address1所指向的變數值(也就
  是num1的值),而&address1則是指標變數本
  身的位址。
 我們可以使用下圖來表示數值、變數、記憶體
  與指標間的關係:




                                    7
指標變數的宣告(2)          8-1 認識指標



   程式範例:指標變數的宣告與使用範例:
    CH08_02.c




                               8
8-1 認識指標




   執行結果




   程式解說

      第9行宣告指標變數指向num1變數的位址。
      第11行則利用&運算子取出num1位址。
      第13行則是輸出此指標變數的位址。            9
指標變數的宣告(3)          8-1 認識指標



   程式範例:指標變數與取值運算子的使用範例:
    CH08_03.c




                               10
8-1 認識指標



   執行結果




   程式解說

     在第10、12行中分別指向相同資料型態的不同變
     數,而在第11、13行中分別輸出指標變數的值與
     指向變數的位址間的比較。                  11
8-1 認識指標
指標變數的宣告(4)
   程式範例:指標變數重新設定範例:CH08_04.c




                                  12
8-1 認識指標


   執行結果




   程式解說
    在第9行中,我們特意使用了input變數來初始化指標的值,
    這邊再次要提醒的是,您不能使用未經初始化的指標。
    第12,行,由於取址運算子與乘法運算子在符號使用上相同,
    您可以使用空白來增加程式的可讀性,此外由於取址運算子
    的優先順序大於乘法運算子,所以不必加上括號。
    第13行中我們特別把求得立方值的*ptr內容輸出,各位會發
    現與它同一位值的input變數值也同步改變了。          13
8-1 認識指標
指標與函數傳遞(1)

   先來回憶一下傳址方式的函數宣告型式如下所示:

    回傳資料型態 函數名稱(資料型態 *參數1, 資料型態 *參數
    2, ……….);
    或
    回傳資料型態 函數名稱(資料型態 *, 資料型態 *, ……….);

   此外,傳址呼叫的函數呼叫型式如下所示:

    函數名稱(&引數1,&引數2, ……….);
                                         14
指標與函數傳遞(2)          8-1 認識指標



   程式範例:氣泡排序法的傳址呼叫範例:
    CH08_05.c




                               15
8-1 認識指標




           16
8-1 認識指標




           17
8-1 認識指標


   執行結果




   程式解說
在本程式中由於swap()函數與BubbleSort( )函數是定義
在main( )函數之前,所以不用原型宣告。
第4行利用兩個指標變數傳入函數內。
第24行接收兩個指向陣列元素的位址。
第38行呼叫BubbleSort( )函數,並將num陣列以傳址呼
叫傳送。                                   18
8-1 認識指標
函數與指標回傳值(1)

   指標回傳函數宣告語法如下:

    回傳資料型態 *函數名稱(資料型態 參數1, 資料型
    態 參數2, ……….)
    {
      ….
       return 指標變數;
     }




                                     19
函數與指標回傳值(2)         8-1 認識指標



   程式範例:函數與指標回傳值的應用範例:
    CH08_06.c




                               20
8-1 認識指標




           21
8-1 認識指標


   執行結果




   程式解說

    第4行是傳回指標值的函數原型宣告,第9行呼叫
    get_pointer_value ()函數,並傳值給ptr指標變數。
    第11行輸出ptr指標變數的內容。
    第19行函數宣告為傳回指標變數。第25行輸入input變
    數的值。
    第28行傳回值為指標變數。                           22
函數與指標回傳值(3)         8-1 認識指標




   程式範例:指標回傳值與函數傳遞的應用範例:
    CH08_07.c




                               23
8-1 認識指標




           24
8-1 認識指標




   執行結果




   程式解說
    第4行宣告傳址呼叫函數min()的原型。
    以ptr指標變數接收函數的指標回傳值。
    第23、24行則直接傳回指標值。                  25
8-1 認識指標
指標的運算

 對於指標的加法或減法運算,只能針對常數值
  (如+1或-1)來進行,不可以做指標變數之間的
  相互運算。
 因為指標變數內容只是存放位址,而位址間的
  運算並沒有任何意義,而且容易讓指標變數指
  向不合法位址。
 以下程式範例中可以發現,對整數型態的指標
  來說每進行一次加法運算,記憶體位址就會向
  右移動4位元組,而對於字元型態的指標而言,
  加法運算則是每次向右移動1位元組。
                               26
8-1 認識指標




   程式範例:指標運算的宣告與應用範例:
    CH08_08.c




                               27
8-1 認識指標




   執行結果




                      28
8-1 認識指標




   程式解說

    第6、7行宣告整數型態指標與字元型態指標變數。
    第13行整數指標變數加一,則記憶體位址就會向右
    移動4位元組。
    第14行字元指標變數加一,則記憶體位址就會向右
    移動1位元組。




                                  29
8-1 認識指標
多重指標(1)

   一個宣告雙重指標的例子如下所示:

    int **ptr;

   雙重指標變數所存放的就是某個指標變數在記
    憶體中的位址,也就是這個ptr就是一個指向指
    標的指標變數。例如我們宣告如下:

    int num=100,*ptr1,**ptr2;
    ptr1=#
    ptr2=&ptr1;
                                           30
8-1 認識指標
多重指標(2)

   程式範例:多重指標的宣告與應用範例:
    CH08_09.c




                               31
8-1 認識指標




   執行結果



   程式解說
第11行中各位可以發現&num的位址和ptr是一樣的,而
*ptr的值也和num相同。
第13行中&ptr1和ptr2相同,ptr1與*ptr2一樣,*ptr1與
                                          32
**ptr2相同。
8-2 指標與陣列的應用
指標與一維陣列(1)

   陣列宣告:

    int arr[6]={312,16,35,65,52,111};

 這時陣列名稱arr就是一個指標常數,也是這個
  陣列的起始位址。
 可以利用指標方式與取值運算子「*」來直接
  存取陣列內的元素值。使用語法如下:

    陣列名稱[索引值]= *陣列名稱(+索引值)
    或
    陣列名稱[索引值]= *(&陣列名稱[索引值])                           33
8-2 指標與陣列的應用
指標與一維陣列(2)

   程式範例:指標常數與一維陣列的宣告與應用
    範例:CH08_10.c




                                34
8-2 指標與陣列的應用




   執行結果




                          35
8-2 指標與陣列的應用




   程式解說

    第7行輸出指標常數arr的值與指標常數arr的位址相同。
    第11行列印陣列與兩種指標常數的替代運算,從執行結
    果中您可以看到,對於int資料型態來說,每加1則位址
    位移4位元組。
    第15行則以兩種指標常數方式來存取陣列內的元素值。




                                     36
8-2 指標與陣列的應用




 我們也可以將陣列的記憶體位址指派給一個指
  標變數,並使用此指標變數來間接顯示陣列元
  素內容。
 有關指標變數取得一維陣列位址的方式如下:


    資料型態 *指標變數=陣列名稱;
    或
    資料型態 *指標變數=&陣列名稱[0];



                                          37
8-2 指標與陣列的應用
指標與一維陣列(3)

   程式範例:指標變數與一維陣列的宣告與應用
    範例:CH08_11.c




                                38
8-2 指標與陣列的應用




   執行結果




                          39
8-2 指標與陣列的應用




   程式解說

    使用指標變數ptr指向陣列常數arr。
    第15、17行輸出arr+i的值與ptr+I的值,兩者顯
    示的位址是相同的。




                                        40
指標與二維陣列(1)          8-2 指標與陣列的應用



   二維陣列具有兩個索引值,這意味著二維陣列
    會有兩個值來控制指定元素相對於第一個元素
    的位移量,為了說明方便,我們以下面這個宣
    告為例:

    int no[2][4];

 在這個例子中,*(no+0)將表示陣列中維度1的
  第一個元素的記憶體位址。
 也就是&no[0][0];而*(no+1)表示陣列中維度2
  的第一個元素的記憶體位址,也就是&no[1][0],
  而*(no+i)表示陣列中維i+1的第一個元素的記憶
  體位址。                             41
8-2 指標與陣列的應用
指標與二維陣列(2)
   程式範例:二維陣列的指標常數表示範例:
    CH08_12.c




                                42
8-2 指標與陣列的應用


   執行結果




   程式解說
    第11行中是輸出使用「&」取址運算子取得二維陣列元素
    位址與指標常數來表示二維陣列元素位址,並可發現要取
    得元素no[i][j]的記憶體位址,則要使用*(no+i)+j來取得。
                                          43
8-2 指標與陣列的應用
指標與二維陣列(3)
   程式範例:二維陣列的指標常數與求值應用範
    例:CH08_13.c




                                44
8-2 指標與陣列的應用


   執行結果




   程式解說

第11行使用*(*(no+i)+j)與no[i][j]來輸出二維陣列的元素值。
依照以上的說明,您也可以推論在三維陣列中,存取元素值
時的三個索引值之真正意義,其實就分別代表了三個記憶體
位移量的控制,而當中必須使用三重指標來計算,這部份的
推論方式與以上的介紹類似。                             45
8-2 指標與陣列的應用
指標與字串(1)

   在C語言中,字串是以字元陣列來實現,指標
    既然可以運用於陣列,則當然也可以運用於字
    串。以下都是字串宣告的合法方式:
    char name[] = { 'J', 'u', 's', 't', '0'};
    char name1[] = "Just";
    char *ptr = "Just";

   使用指標的觀念來處理字串,會比使用陣列來
    得方便許多,宣告格式如下:

    char *指標變數="字串內容";
                                                                46
指標與字串(2)         8-2 指標與陣列的應用



   程式範例:指標與字串的宣告與使用範例:
    CH08_14.c




                                47
8-2 指標與陣列的應用




               48
8-2 指標與陣列的應用



   執行結果




                          49
8-2 指標與陣列的應用




   程式解說

    第7行以以指標變數宣告字串方式,第8行則以字元陣列
    宣告字串方式。
    在第11行輸出的ptr所佔空間大小4位元,是因為ptr所存
    放的是整數位址。
    至於sizeof(name)則輸出包含‘0’共7位元。
    第16行則以指標變數及指標常數輸出字串。
    第21行則將指標變數及指標常數以陣列方式及逐一讀值
    方式輸出字元。
    第26、27行則執行指標運算,並輸出當時的位址。

                                     50
指標與字串(3)         8-2 指標與陣列的應用



   程式範例:字串傳遞與大小寫字母互相轉換應
    用範例:CH08_15.c




                                51
8-2 指標與陣列的應用




               52
8-2 指標與陣列的應用




               53
8-2 指標與陣列的應用

   執行結果




   程式解說
第9行中是以陣列字元宣告字串,第24、40行則利用指標
變數接收參數字串。
第29、46行則將函數中的指標變數逐一計算字元總數。
第34、51行的主要技巧是利用指標變數逐一讀出字元與在
ASCII編碼中,英文小寫字母編碼為97~122,而大寫字母
為65~90,中間的編碼數值差為32,而字元在記憶體中其
實是以整數型態儲存,所以我們只要對字元加32或減32,
就可以直接轉換字母的大小寫。
                                   54
8-2 指標與陣列的應用




 以下程式範例是使用指標來進行Strcat()字串函
  數串接實作,並將指標當作傳回值。
 技巧就是首先必須找出被串接字串的尾端,然
  後將要的串接字串中之字元一一指定至被串接
  字串之後,此外最後串接後的字串中英文字母
  的部份都改為大寫字元。




                                 55
8-2 指標與陣列的應用


   程式範例:指標傳回值Strcat()字串函數實作範
    例:CH08_16.c




                                   56
8-2 指標與陣列的應用




               57
8-2 指標與陣列的應用




   執行結果


                          58
8-2 指標與陣列的應用




   程式解說

    第4行是指標傳回值的字串串接函數。
    第8、9行宣告兩個有60字元的字串陣列。
    第28行尋找str1的結束字元‘0’位置,並計算i的長度,第
    31~32行將小寫字元轉為大寫。第36~37行逐一加上str2
    的字元,並將小寫字元轉為大寫。
    第41行加上空字元,代表字串結束。




                                       59
8-2 指標與陣列的應用
指標陣列(1)

   一維指標陣列的宣告格式:

    資料型態 *陣列名稱[元素名稱];

   例如以下是宣告一個名稱為p的整數指標陣列,
    每個元素(p[i])皆可指向一整數值,另外一個則
    是宣告一個名稱為ptr的浮點數指標陣列:

    int *p[3];
    float *ptr[4];

                                       60
8-2 指標與陣列的應用



 一維指標陣列的應用特別在儲存字串上相當實用。
 例如之前介紹使用二維字元陣列,當一個字串陣列
  的宣告方式如下所示:

    char name[4][11] = { "apple", "watermelon", "Banana",
    "orange" };

   為了避免記憶體空間的浪費,我們就相當適合使用
    「指標陣列」來儲存字串,我們可以將之前的宣告
    更改為以下的方式:
    char *name[4] = { "apple", "watermelon", "Banana",
    "orange" };                                             61
指標陣列(2)          8-2 指標與陣列的應用


   程式範例:一維指標陣列與字串儲存的應用範
    例:CH08_17.c




                                62
8-2 指標與陣列的應用



   執行結果




   程式解說
    我們於第06行宣告陣列時加入了一個空字串,這是
    為了方便計算指標陣列儲存字串時所佔有的空間。
    在第11行列印字串內容及儲存起始位址。
    第12行各位可從兩個位址相減會得到位移量來判斷
    所佔用儲存空間。                       63
指標陣列(3)          8-2 指標與陣列的應用



   程式範例:一維指標陣列與氣泡排序法的應用
    範例:CH08_18.c




                                64
8-2 指標與陣列的應用




               65
8-2 指標與陣列的應用



   執行結果




   程式解說
第7行宣告並設定字串陣列內容。
第10行宣告一維指標陣列及字元指標變數。
第17行將一維指標陣列每個元素指向字串陣列的每個位址。
第31行輸出排序後一維指標陣列的內容。
                                66
8-3 動態配置記憶體
動態配置變數(1)

   動態配置一般變數的方式如下,如果n=1,即
    表示一個變數:

資料型態* 指標名稱=(資料型態*)malloc(sizeof(資料型態)*n);

   當執行時期動態配置的一般變數不需要時,可
    以將其釋放,釋放動態配置的一般變數的方式
    如下:

    free(指標名稱);

                                         67
動態配置變數(2)         8-3 動態配置記憶體



   程式範例:動態配置變數的宣告與應用範例:
    CH08_19.c




                                68
8-3 動態配置記憶體




              69
8-3 動態配置記憶體



   執行結果




   程式解說
    第6、8行將浮點數與整數指標指向動態配置記憶空間。
    第7、9行分別設定浮點數與整數指標變數的起始值。
    第15、16行使用free()函數釋放piVal與 piCal指標所指
    向的記憶體空間。                              70
動態配置變數(3)         8-3 動態配置記憶體



   程式範例:動態配置字串變數的宣告與應用範
    例:CH08_20.c




                                71
8-3 動態配置記憶體




   執行結果




                         72
8-3 動態配置記憶體




   程式解說

    第7行動態配置記憶與str1字串相同大小空間,而第
    10行將str1字串複製到str2字串。
    第13行輸出str2的位址與所指向的內容值。
    第15行釋放str2字串記憶空間。
    第13行輸出釋放後的str2位址與所指向的內容值。




                                    73
8-3 動態配置記憶體
動態配置陣列(1)

   動態配置一維陣列的方式如下,n=陣列長度:

資料型態* 指標名稱=(資料型態*)malloc(n*sizeof(資料型態));

   當執行時期動態配置的一維陣列不需要時,可
    以將其釋放,釋放動態配置的一維陣列的方式
    如下:

    free(指標名稱);


                                         74
動態配置陣列(2)         8-3 動態配置記憶體


   程式範例:動態配置一維陣列的宣告與應用範
    例:CH08_21.c




                                75
8-3 動態配置記憶體




              76
8-3 動態配置記憶體


   執行結果




                         77
8-3 動態配置記憶體




   程式解說

    第10行請輸入欲產生的動態一維陣列個數,第11行
    將整數指標指向動態配置一維陣列記憶空間。
    第13~16行輸入max個數的陣列元素值。
    第24行釋放指標指向的記憶空間。




                                   78
8-4 上機實習課程
上機實習課程(1)

   上機實習範例:CH08_22.c
    – 以下程式範例是利用指標常數方式來表示三維
      陣列元素位址的方法與直接使用「&」取址運算
      子取得三維陣列元素位址的比較。
    – arr陣列元素內容如下:

     A[4][3][3]={{{1,-2,3},{4,5,-6},{8,9,2}},
            {{7,-8,9},{10,11,12},{0.8,3,2}},
            {{-13,14,15},{16,17,18},{3,6,7}},
            {{19,20,21},{-22,23,24},(6-,9,12)}};
                                                        79
8-4 上機實習課程




             80
8-4 上機實習課程




             81
8-4 上機實習課程




   執行結果




                        82
8-4 上機實習課程
上機實習課程(2)

   上機實習範例:CH08_23.c
    – 延續上題,以下程式範例是利用指標常數方式
     來取得以下三維陣列arr的元數值,並計算每個
     陣列元素值總和。




                                    83
8-4 上機實習課程




   執行結果



                        84
上機實習課程(3)              8-4 上機實習課程



   上機實習範例:CH08_24.c
    – 以下程式範例中利用指標變數指向arr陣列,並
     將此指標變數傳遞到計算次方值的cubic()函數,
     再利用函數中的指標變數加法運算,來將每一
     個元素值次方運算及所有新元素的總和。最後
     再輸出所有新元素及總和。




                                    85
8-4 上機實習課程




             86
8-4 上機實習課程




   執行結果




                        87
8-4 上機實習課程
上機實習課程(4)

   上機實習範例:CH08_25.c
    – 現在有三個整數陣列num1、num2、num3,其
     中分別存放二位數整數、三位數整數與四位數
     整數,如下所示:

     int num1[]={ 15,23,31 };
     int num2[]={ 114,225,336 };
     int num3[]={ 1237,3358,9271 };

    – 請設計一程式,利用指標陣列的三個元素值指
     向這三個陣列,並透過這個指標陣列來輸出此
     三個整數陣列的所有元素值。
                                                   88
8-4 上機實習課程




             89
8-4 上機實習課程




   執行結果




                        90
8-4 上機實習課程
上機實習課程(5)
   上機實習範例:CH08_26.c
    – 以下程式範例只要是說明函數名稱本身也代表
     了一個記憶體位址,當您呼叫函數時,其實就
     是在告訴程式,執行該函數名稱所指向的記憶
     體位址中之程式,這與函數後加上括號的呼叫
     方式是有不同。




                                    91
8-4 上機實習課程




   執行結果




                        92
8-4 上機實習課程
上機實習課程(6)

   上機實習範例:CH08_27.c
    – 延續上題的概念,函數名稱其實也是個指標變
      數,其本身所儲存的值為函數內容所在的記憶
      體起始位址,因此函數也可當成指標來宣告,
      稱為「函式指標」。
    – 其作用在於使用同一個函式指標名稱,主要作
      用在於程式執行期間動態地決定該呼叫的函式。
      宣告方式如下:

     資料型態 (*ptr)(參數1, 參數2, …)
                                             93
8-4 上機實習課程




             94
8-4 上機實習課程




   執行結果


                        95
上機實習課程(7)                                8-4 上機實習課程



   上機實習範例:CH08_28.c
    – 請將一個整數指標變數指向二維陣列arr,並利
      用指標運算將陣列中每一個元素值輸出。
    – arr陣列內容如下:

     arr[4][3]={312,16,35,65,52,111,66,88,44,55,99,100};




                                                           96
8-4 上機實習課程




   執行結果


                        97
8-4 上機實習課程
上機實習課程(8)

   上機實習範例:CH08_29.c
    – 請將一個字元指標變數指向由使用者輸入的字串,
     並利用指標運算將字串中每一個字元輸出。




                                    98
8-4 上機實習課程




   執行結果


                        99
8-4 上機實習課程
上機實習課程(9)

   上機實習範例:CH08_30.c
    – 請設計一函數replace(),可在使用者所輸入的
     字串中指定位置及打算更換的字元,函數中將
     使用字元指標來處理運算及置換過程。




                                     100
8-4 上機實習課程




             101
8-4 上機實習課程




   執行結果




                        102
上機實習課程(10)             8-4 上機實習課程



   上機實習範例:CH08_31.c
    – 下面這個程式範例則是說明了三重指標的宣告
     與使用方法,依據相同的方法也可以宣告更多
     重指標。




                                    103
8-4 上機實習課程




   執行結果




                        104
8-4 上機實習課程
上機實習課程(11)

   上機實習範例:CH08_32.c
    – 我們宣告一個指標變數p1並設定它的初值為指向
     陣列變數array1的第五個元素的記憶體位址:

     int i,array1[5]={100,200,300,400,500};
     int *p1=array1;
     p1=&array1[4];

    – 例如當我們將指標變數p1減1之後,就是將目前指
     標變數p1所指向的記憶體位址往前移動1次,也就
     是指向陣列變數array1的第四個元素,請看以下
     程式碼的實作驗證。
                                                     105
8-4 上機實習課程




             106
8-4 上機實習課程




   執行結果




                        107
8-4 上機實習課程
上機實習課程(12)

   上機實習範例:CH08_33.c
    – 以下程式範例是利用指標常數方式來表示三維
      陣列元素位址的方法與直接使用「&」取址運算
      子取得三維陣列元素位址的比較。
    – arr陣列元素內容如下:

      A[4][3][3]={{{1,-2,3},{4,5,-6},{8,9,2}},
             {{7,-8,9},{10,11,12},{8,3,2}},
             {{-13,14,15},{16,17,18},{3,6,7}},
             {{19,20,21},{-22,23,24},(-6,9,12)}};
                                                       108
8-4 上機實習課程




             109
8-4 上機實習課程




             110
8-4 上機實習課程




   執行結果




                        111
上機實習課程(13)             8-4 上機實習課程



   上機實習範例:CH08_34.c
    – 以下程式範例是說明如果使用指標變數*ptr來存
     取二維陣列中第i列的第j行元素可以利用如下公
     式來取出該元素值:

     *(ptr+i*m+j);




                                    112
8-4 上機實習課程




   執行結果




                        113
上機實習課程(14)             8-4 上機實習課程



   上機實習範例:CH08_35.c
    – 下面的範例程式以兩種不同方式建立字串,並利用
     指標讀出其中的各個字元,顯示於螢幕中。




                                    114
8-4 上機實習課程




   執行結果



                        115
8-4 上機實習課程
上機實習課程(15)

   上機實習範例:CH08_36.c
    – 以下程式範例是先取得使用者輸入字串,然後
     比對是否和字串指標陣列中的某個字串相同。




                                    116
8-4 上機實習課程




             117
8-4 上機實習課程




   執行結果




                        118

More Related Content

What's hot (20)

第6章指针
第6章指针第6章指针
第6章指针
 
Python基本資料運算
Python基本資料運算Python基本資料運算
Python基本資料運算
 
系統程式 -- 第 8 章 編譯器
系統程式 -- 第 8 章 編譯器系統程式 -- 第 8 章 編譯器
系統程式 -- 第 8 章 編譯器
 
建置Python開發環境
建置Python開發環境建置Python開發環境
建置Python開發環境
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
C語言結構與串列
C語言結構與串列 C語言結構與串列
C語言結構與串列
 
Python分支作業
Python分支作業Python分支作業
Python分支作業
 
Ch10
Ch10Ch10
Ch10
 
第8章结构体与共用体
第8章结构体与共用体第8章结构体与共用体
第8章结构体与共用体
 
实验一 Mathematica软件简介
实验一   Mathematica软件简介实验一   Mathematica软件简介
实验一 Mathematica软件简介
 
Python變數與資料運算
Python變數與資料運算Python變數與資料運算
Python變數與資料運算
 
Ch10 範例
Ch10 範例Ch10 範例
Ch10 範例
 
Python 迴圈作業
Python 迴圈作業Python 迴圈作業
Python 迴圈作業
 
系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作系統程式 -- 第 12 章 系統軟體實作
系統程式 -- 第 12 章 系統軟體實作
 
Ch 6
Ch 6Ch 6
Ch 6
 
Excel使用技巧
Excel使用技巧Excel使用技巧
Excel使用技巧
 
Matlab 在機率與統計的應用
Matlab 在機率與統計的應用Matlab 在機率與統計的應用
Matlab 在機率與統計的應用
 
C語言標準輸出入函式
C語言標準輸出入函式C語言標準輸出入函式
C語言標準輸出入函式
 
C語言 第五章 程式流程控制
C語言 第五章 程式流程控制C語言 第五章 程式流程控制
C語言 第五章 程式流程控制
 
1 C入門教學
1  C入門教學1  C入門教學
1 C入門教學
 

Similar to 08 指標

Tdxgongshi
TdxgongshiTdxgongshi
Tdxgongshiairsina
 
第9章 transact sql程序设计
第9章   transact sql程序设计第9章   transact sql程序设计
第9章 transact sql程序设计hanmo1988
 
C++模板与泛型编程
C++模板与泛型编程C++模板与泛型编程
C++模板与泛型编程deer hope
 
C語言 第二章 02 C的資料處理
C語言 第二章 02 C的資料處理C語言 第二章 02 C的資料處理
C語言 第二章 02 C的資料處理shademoon
 
UNIT 11 一级指针——指针基本篇.ppt
UNIT 11 一级指针——指针基本篇.pptUNIT 11 一级指针——指针基本篇.ppt
UNIT 11 一级指针——指针基本篇.pptxianbingwang1
 
第2章数据类型、运算符和表达式
第2章数据类型、运算符和表达式第2章数据类型、运算符和表达式
第2章数据类型、运算符和表达式summerfeng
 
软件工程 第二章
软件工程 第二章软件工程 第二章
软件工程 第二章浒 刘
 
Python 脚本入门基础
Python 脚本入门基础Python 脚本入门基础
Python 脚本入门基础wklken
 
System verilog简介
System verilog简介System verilog简介
System verilog简介wujianping
 
第1章 Matlab操作基础
第1章  Matlab操作基础第1章  Matlab操作基础
第1章 Matlab操作基础eterou
 
基本遗传算法
 基本遗传算法 基本遗传算法
基本遗传算法sixu05202004
 
Slide08 807007748
Slide08 807007748Slide08 807007748
Slide08 807007748Shiyao Ma
 
Oracle经典教程
Oracle经典教程Oracle经典教程
Oracle经典教程yiditushe
 
物件導向設計原理及設計樣式
物件導向設計原理及設計樣式物件導向設計原理及設計樣式
物件導向設計原理及設計樣式Y YU
 
C 02 c语言的基本数据类型与表达式
C 02 c语言的基本数据类型与表达式C 02 c语言的基本数据类型与表达式
C 02 c语言的基本数据类型与表达式1138177709
 
Sql培训 (1)
Sql培训 (1)Sql培训 (1)
Sql培训 (1)jhao niu
 

Similar to 08 指標 (20)

Tdxgongshi
TdxgongshiTdxgongshi
Tdxgongshi
 
第9章 transact sql程序设计
第9章   transact sql程序设计第9章   transact sql程序设计
第9章 transact sql程序设计
 
C++模板与泛型编程
C++模板与泛型编程C++模板与泛型编程
C++模板与泛型编程
 
第5章数组
第5章数组第5章数组
第5章数组
 
C語言 第二章 02 C的資料處理
C語言 第二章 02 C的資料處理C語言 第二章 02 C的資料處理
C語言 第二章 02 C的資料處理
 
UNIT 11 一级指针——指针基本篇.ppt
UNIT 11 一级指针——指针基本篇.pptUNIT 11 一级指针——指针基本篇.ppt
UNIT 11 一级指针——指针基本篇.ppt
 
Ch10
Ch10Ch10
Ch10
 
香港六合彩
香港六合彩香港六合彩
香港六合彩
 
第2章数据类型、运算符和表达式
第2章数据类型、运算符和表达式第2章数据类型、运算符和表达式
第2章数据类型、运算符和表达式
 
软件工程 第二章
软件工程 第二章软件工程 第二章
软件工程 第二章
 
Python 脚本入门基础
Python 脚本入门基础Python 脚本入门基础
Python 脚本入门基础
 
System verilog简介
System verilog简介System verilog简介
System verilog简介
 
第1章 Matlab操作基础
第1章  Matlab操作基础第1章  Matlab操作基础
第1章 Matlab操作基础
 
系統程式 -- 第 8 章
系統程式 -- 第 8 章系統程式 -- 第 8 章
系統程式 -- 第 8 章
 
基本遗传算法
 基本遗传算法 基本遗传算法
基本遗传算法
 
Slide08 807007748
Slide08 807007748Slide08 807007748
Slide08 807007748
 
Oracle经典教程
Oracle经典教程Oracle经典教程
Oracle经典教程
 
物件導向設計原理及設計樣式
物件導向設計原理及設計樣式物件導向設計原理及設計樣式
物件導向設計原理及設計樣式
 
C 02 c语言的基本数据类型与表达式
C 02 c语言的基本数据类型与表达式C 02 c语言的基本数据类型与表达式
C 02 c语言的基本数据类型与表达式
 
Sql培训 (1)
Sql培训 (1)Sql培训 (1)
Sql培训 (1)
 

More from shademoon

10 檔案說明與處理
10 檔案說明與處理10 檔案說明與處理
10 檔案說明與處理shademoon
 
06 函數與巨集
06 函數與巨集06 函數與巨集
06 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集shademoon
 
C語言 第五章 Ch05 05
C語言 第五章 Ch05 05C語言 第五章 Ch05 05
C語言 第五章 Ch05 05shademoon
 
C語言 第五章 Ch05 18
C語言 第五章 Ch05 18C語言 第五章 Ch05 18
C語言 第五章 Ch05 18shademoon
 
C語言 第4章 Ch04 02
C語言 第4章 Ch04 02C語言 第4章 Ch04 02
C語言 第4章 Ch04 02shademoon
 
C語言 第4章 Ch04 01
C語言 第4章 Ch04 01C語言 第4章 Ch04 01
C語言 第4章 Ch04 01shademoon
 
C語言 第三章 03 運算子、運算元與運算式
C語言 第三章 03 運算子、運算元與運算式C語言 第三章 03 運算子、運算元與運算式
C語言 第三章 03 運算子、運算元與運算式shademoon
 
C語言 第一章 C語言簡介
C語言 第一章 C語言簡介C語言 第一章 C語言簡介
C語言 第一章 C語言簡介shademoon
 
計概筆記2
計概筆記2計概筆記2
計概筆記2shademoon
 
3 11英文單字
3 11英文單字3 11英文單字
3 11英文單字shademoon
 
計概筆記1
計概筆記1計概筆記1
計概筆記1shademoon
 

More from shademoon (19)

10 檔案說明與處理
10 檔案說明與處理10 檔案說明與處理
10 檔案說明與處理
 
06 函數與巨集
06 函數與巨集06 函數與巨集
06 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
第六章 函數與巨集
第六章 函數與巨集第六章 函數與巨集
第六章 函數與巨集
 
C語言 第五章 Ch05 05
C語言 第五章 Ch05 05C語言 第五章 Ch05 05
C語言 第五章 Ch05 05
 
C語言 第五章 Ch05 18
C語言 第五章 Ch05 18C語言 第五章 Ch05 18
C語言 第五章 Ch05 18
 
C語言 第4章 Ch04 02
C語言 第4章 Ch04 02C語言 第4章 Ch04 02
C語言 第4章 Ch04 02
 
C語言 第4章 Ch04 01
C語言 第4章 Ch04 01C語言 第4章 Ch04 01
C語言 第4章 Ch04 01
 
C語言 第三章 03 運算子、運算元與運算式
C語言 第三章 03 運算子、運算元與運算式C語言 第三章 03 運算子、運算元與運算式
C語言 第三章 03 運算子、運算元與運算式
 
C語言 第一章 C語言簡介
C語言 第一章 C語言簡介C語言 第一章 C語言簡介
C語言 第一章 C語言簡介
 
計概筆記2
計概筆記2計概筆記2
計概筆記2
 
3 11英文單字
3 11英文單字3 11英文單字
3 11英文單字
 
計概筆記1
計概筆記1計概筆記1
計概筆記1
 

08 指標

  • 2. 8-1 認識指標 認識指標(1)  指標與記憶體有著相當密切的關係。  現在請您思考一個問題,變數是用來儲存數值, 而數值究竟儲存在記憶體中的哪個位址上呢?  相當簡單,如果要了解變數所在記憶體位址, 只要透過 &(取址運算子)就能求出變數所在 的位址。語法格式如下: &變數名稱; 2
  • 3. 認識指標(2) 8-1 認識指標  程式範例:&(取址運算子)的宣告與使用範例: CH08_01.c 3
  • 4. 8-1 認識指標  執行結果  程式解說 第6~8行分別宣告三種不同型態的變數,第10~12行則 以%p格式來表示16進位的位址,如果要取出變數的位 址只要在變數前加上&運算子即可。 4
  • 5. 8-1 認識指標 指標變數的宣告(1)  指標的宣告方式如下: 資料型態 *指標名稱; 或 資料型態* 指標名稱;  以下是幾個指標變數的宣告方式: int* x; int *x, *y; 5
  • 6. 8-1 認識指標  在宣告指標時,我們可以將*置放於型態宣告 的關鍵字旁,或是變數名稱旁邊,通常若要宣 告兩個以上的變數,會將*靠在變數名稱旁, 增加可讀性。  當然指標變數宣告時也可設定初值為0或是 NULL來增加可讀性: int *x=0; int *y=NULL; 6
  • 7. 8-1 認識指標  以下程式是很經典的指標範例,主要是說明指 標變數address1的儲存內容是位址, *address1則是address1所指向的變數值(也就 是num1的值),而&address1則是指標變數本 身的位址。  我們可以使用下圖來表示數值、變數、記憶體 與指標間的關係: 7
  • 8. 指標變數的宣告(2) 8-1 認識指標  程式範例:指標變數的宣告與使用範例: CH08_02.c 8
  • 9. 8-1 認識指標  執行結果  程式解說 第9行宣告指標變數指向num1變數的位址。 第11行則利用&運算子取出num1位址。 第13行則是輸出此指標變數的位址。 9
  • 10. 指標變數的宣告(3) 8-1 認識指標  程式範例:指標變數與取值運算子的使用範例: CH08_03.c 10
  • 11. 8-1 認識指標  執行結果  程式解說 在第10、12行中分別指向相同資料型態的不同變 數,而在第11、13行中分別輸出指標變數的值與 指向變數的位址間的比較。 11
  • 12. 8-1 認識指標 指標變數的宣告(4)  程式範例:指標變數重新設定範例:CH08_04.c 12
  • 13. 8-1 認識指標  執行結果  程式解說 在第9行中,我們特意使用了input變數來初始化指標的值, 這邊再次要提醒的是,您不能使用未經初始化的指標。 第12,行,由於取址運算子與乘法運算子在符號使用上相同, 您可以使用空白來增加程式的可讀性,此外由於取址運算子 的優先順序大於乘法運算子,所以不必加上括號。 第13行中我們特別把求得立方值的*ptr內容輸出,各位會發 現與它同一位值的input變數值也同步改變了。 13
  • 14. 8-1 認識指標 指標與函數傳遞(1)  先來回憶一下傳址方式的函數宣告型式如下所示: 回傳資料型態 函數名稱(資料型態 *參數1, 資料型態 *參數 2, ……….); 或 回傳資料型態 函數名稱(資料型態 *, 資料型態 *, ……….);  此外,傳址呼叫的函數呼叫型式如下所示: 函數名稱(&引數1,&引數2, ……….); 14
  • 15. 指標與函數傳遞(2) 8-1 認識指標  程式範例:氣泡排序法的傳址呼叫範例: CH08_05.c 15
  • 18. 8-1 認識指標  執行結果  程式解說 在本程式中由於swap()函數與BubbleSort( )函數是定義 在main( )函數之前,所以不用原型宣告。 第4行利用兩個指標變數傳入函數內。 第24行接收兩個指向陣列元素的位址。 第38行呼叫BubbleSort( )函數,並將num陣列以傳址呼 叫傳送。 18
  • 19. 8-1 認識指標 函數與指標回傳值(1)  指標回傳函數宣告語法如下: 回傳資料型態 *函數名稱(資料型態 參數1, 資料型 態 參數2, ……….) { …. return 指標變數; } 19
  • 20. 函數與指標回傳值(2) 8-1 認識指標  程式範例:函數與指標回傳值的應用範例: CH08_06.c 20
  • 22. 8-1 認識指標  執行結果  程式解說 第4行是傳回指標值的函數原型宣告,第9行呼叫 get_pointer_value ()函數,並傳值給ptr指標變數。 第11行輸出ptr指標變數的內容。 第19行函數宣告為傳回指標變數。第25行輸入input變 數的值。 第28行傳回值為指標變數。 22
  • 23. 函數與指標回傳值(3) 8-1 認識指標  程式範例:指標回傳值與函數傳遞的應用範例: CH08_07.c 23
  • 25. 8-1 認識指標  執行結果  程式解說 第4行宣告傳址呼叫函數min()的原型。 以ptr指標變數接收函數的指標回傳值。 第23、24行則直接傳回指標值。 25
  • 26. 8-1 認識指標 指標的運算  對於指標的加法或減法運算,只能針對常數值 (如+1或-1)來進行,不可以做指標變數之間的 相互運算。  因為指標變數內容只是存放位址,而位址間的 運算並沒有任何意義,而且容易讓指標變數指 向不合法位址。  以下程式範例中可以發現,對整數型態的指標 來說每進行一次加法運算,記憶體位址就會向 右移動4位元組,而對於字元型態的指標而言, 加法運算則是每次向右移動1位元組。 26
  • 27. 8-1 認識指標  程式範例:指標運算的宣告與應用範例: CH08_08.c 27
  • 28. 8-1 認識指標  執行結果 28
  • 29. 8-1 認識指標  程式解說 第6、7行宣告整數型態指標與字元型態指標變數。 第13行整數指標變數加一,則記憶體位址就會向右 移動4位元組。 第14行字元指標變數加一,則記憶體位址就會向右 移動1位元組。 29
  • 30. 8-1 認識指標 多重指標(1)  一個宣告雙重指標的例子如下所示: int **ptr;  雙重指標變數所存放的就是某個指標變數在記 憶體中的位址,也就是這個ptr就是一個指向指 標的指標變數。例如我們宣告如下: int num=100,*ptr1,**ptr2; ptr1=# ptr2=&ptr1; 30
  • 31. 8-1 認識指標 多重指標(2)  程式範例:多重指標的宣告與應用範例: CH08_09.c 31
  • 32. 8-1 認識指標  執行結果  程式解說 第11行中各位可以發現&num的位址和ptr是一樣的,而 *ptr的值也和num相同。 第13行中&ptr1和ptr2相同,ptr1與*ptr2一樣,*ptr1與 32 **ptr2相同。
  • 33. 8-2 指標與陣列的應用 指標與一維陣列(1)  陣列宣告: int arr[6]={312,16,35,65,52,111};  這時陣列名稱arr就是一個指標常數,也是這個 陣列的起始位址。  可以利用指標方式與取值運算子「*」來直接 存取陣列內的元素值。使用語法如下: 陣列名稱[索引值]= *陣列名稱(+索引值) 或 陣列名稱[索引值]= *(&陣列名稱[索引值]) 33
  • 34. 8-2 指標與陣列的應用 指標與一維陣列(2)  程式範例:指標常數與一維陣列的宣告與應用 範例:CH08_10.c 34
  • 36. 8-2 指標與陣列的應用  程式解說 第7行輸出指標常數arr的值與指標常數arr的位址相同。 第11行列印陣列與兩種指標常數的替代運算,從執行結 果中您可以看到,對於int資料型態來說,每加1則位址 位移4位元組。 第15行則以兩種指標常數方式來存取陣列內的元素值。 36
  • 37. 8-2 指標與陣列的應用  我們也可以將陣列的記憶體位址指派給一個指 標變數,並使用此指標變數來間接顯示陣列元 素內容。  有關指標變數取得一維陣列位址的方式如下: 資料型態 *指標變數=陣列名稱; 或 資料型態 *指標變數=&陣列名稱[0]; 37
  • 38. 8-2 指標與陣列的應用 指標與一維陣列(3)  程式範例:指標變數與一維陣列的宣告與應用 範例:CH08_11.c 38
  • 40. 8-2 指標與陣列的應用  程式解說 使用指標變數ptr指向陣列常數arr。 第15、17行輸出arr+i的值與ptr+I的值,兩者顯 示的位址是相同的。 40
  • 41. 指標與二維陣列(1) 8-2 指標與陣列的應用  二維陣列具有兩個索引值,這意味著二維陣列 會有兩個值來控制指定元素相對於第一個元素 的位移量,為了說明方便,我們以下面這個宣 告為例: int no[2][4];  在這個例子中,*(no+0)將表示陣列中維度1的 第一個元素的記憶體位址。  也就是&no[0][0];而*(no+1)表示陣列中維度2 的第一個元素的記憶體位址,也就是&no[1][0], 而*(no+i)表示陣列中維i+1的第一個元素的記憶 體位址。 41
  • 42. 8-2 指標與陣列的應用 指標與二維陣列(2)  程式範例:二維陣列的指標常數表示範例: CH08_12.c 42
  • 43. 8-2 指標與陣列的應用  執行結果  程式解說 第11行中是輸出使用「&」取址運算子取得二維陣列元素 位址與指標常數來表示二維陣列元素位址,並可發現要取 得元素no[i][j]的記憶體位址,則要使用*(no+i)+j來取得。 43
  • 44. 8-2 指標與陣列的應用 指標與二維陣列(3)  程式範例:二維陣列的指標常數與求值應用範 例:CH08_13.c 44
  • 45. 8-2 指標與陣列的應用  執行結果  程式解說 第11行使用*(*(no+i)+j)與no[i][j]來輸出二維陣列的元素值。 依照以上的說明,您也可以推論在三維陣列中,存取元素值 時的三個索引值之真正意義,其實就分別代表了三個記憶體 位移量的控制,而當中必須使用三重指標來計算,這部份的 推論方式與以上的介紹類似。 45
  • 46. 8-2 指標與陣列的應用 指標與字串(1)  在C語言中,字串是以字元陣列來實現,指標 既然可以運用於陣列,則當然也可以運用於字 串。以下都是字串宣告的合法方式: char name[] = { 'J', 'u', 's', 't', '0'}; char name1[] = "Just"; char *ptr = "Just";  使用指標的觀念來處理字串,會比使用陣列來 得方便許多,宣告格式如下: char *指標變數="字串內容"; 46
  • 47. 指標與字串(2) 8-2 指標與陣列的應用  程式範例:指標與字串的宣告與使用範例: CH08_14.c 47
  • 50. 8-2 指標與陣列的應用  程式解說 第7行以以指標變數宣告字串方式,第8行則以字元陣列 宣告字串方式。 在第11行輸出的ptr所佔空間大小4位元,是因為ptr所存 放的是整數位址。 至於sizeof(name)則輸出包含‘0’共7位元。 第16行則以指標變數及指標常數輸出字串。 第21行則將指標變數及指標常數以陣列方式及逐一讀值 方式輸出字元。 第26、27行則執行指標運算,並輸出當時的位址。 50
  • 51. 指標與字串(3) 8-2 指標與陣列的應用  程式範例:字串傳遞與大小寫字母互相轉換應 用範例:CH08_15.c 51
  • 54. 8-2 指標與陣列的應用  執行結果  程式解說 第9行中是以陣列字元宣告字串,第24、40行則利用指標 變數接收參數字串。 第29、46行則將函數中的指標變數逐一計算字元總數。 第34、51行的主要技巧是利用指標變數逐一讀出字元與在 ASCII編碼中,英文小寫字母編碼為97~122,而大寫字母 為65~90,中間的編碼數值差為32,而字元在記憶體中其 實是以整數型態儲存,所以我們只要對字元加32或減32, 就可以直接轉換字母的大小寫。 54
  • 55. 8-2 指標與陣列的應用  以下程式範例是使用指標來進行Strcat()字串函 數串接實作,並將指標當作傳回值。  技巧就是首先必須找出被串接字串的尾端,然 後將要的串接字串中之字元一一指定至被串接 字串之後,此外最後串接後的字串中英文字母 的部份都改為大寫字元。 55
  • 56. 8-2 指標與陣列的應用  程式範例:指標傳回值Strcat()字串函數實作範 例:CH08_16.c 56
  • 59. 8-2 指標與陣列的應用  程式解說 第4行是指標傳回值的字串串接函數。 第8、9行宣告兩個有60字元的字串陣列。 第28行尋找str1的結束字元‘0’位置,並計算i的長度,第 31~32行將小寫字元轉為大寫。第36~37行逐一加上str2 的字元,並將小寫字元轉為大寫。 第41行加上空字元,代表字串結束。 59
  • 60. 8-2 指標與陣列的應用 指標陣列(1)  一維指標陣列的宣告格式: 資料型態 *陣列名稱[元素名稱];  例如以下是宣告一個名稱為p的整數指標陣列, 每個元素(p[i])皆可指向一整數值,另外一個則 是宣告一個名稱為ptr的浮點數指標陣列: int *p[3]; float *ptr[4]; 60
  • 61. 8-2 指標與陣列的應用  一維指標陣列的應用特別在儲存字串上相當實用。  例如之前介紹使用二維字元陣列,當一個字串陣列 的宣告方式如下所示: char name[4][11] = { "apple", "watermelon", "Banana", "orange" };  為了避免記憶體空間的浪費,我們就相當適合使用 「指標陣列」來儲存字串,我們可以將之前的宣告 更改為以下的方式: char *name[4] = { "apple", "watermelon", "Banana", "orange" }; 61
  • 62. 指標陣列(2) 8-2 指標與陣列的應用  程式範例:一維指標陣列與字串儲存的應用範 例:CH08_17.c 62
  • 63. 8-2 指標與陣列的應用  執行結果  程式解說 我們於第06行宣告陣列時加入了一個空字串,這是 為了方便計算指標陣列儲存字串時所佔有的空間。 在第11行列印字串內容及儲存起始位址。 第12行各位可從兩個位址相減會得到位移量來判斷 所佔用儲存空間。 63
  • 64. 指標陣列(3) 8-2 指標與陣列的應用  程式範例:一維指標陣列與氣泡排序法的應用 範例:CH08_18.c 64
  • 66. 8-2 指標與陣列的應用  執行結果  程式解說 第7行宣告並設定字串陣列內容。 第10行宣告一維指標陣列及字元指標變數。 第17行將一維指標陣列每個元素指向字串陣列的每個位址。 第31行輸出排序後一維指標陣列的內容。 66
  • 67. 8-3 動態配置記憶體 動態配置變數(1)  動態配置一般變數的方式如下,如果n=1,即 表示一個變數: 資料型態* 指標名稱=(資料型態*)malloc(sizeof(資料型態)*n);  當執行時期動態配置的一般變數不需要時,可 以將其釋放,釋放動態配置的一般變數的方式 如下: free(指標名稱); 67
  • 68. 動態配置變數(2) 8-3 動態配置記憶體  程式範例:動態配置變數的宣告與應用範例: CH08_19.c 68
  • 70. 8-3 動態配置記憶體  執行結果  程式解說 第6、8行將浮點數與整數指標指向動態配置記憶空間。 第7、9行分別設定浮點數與整數指標變數的起始值。 第15、16行使用free()函數釋放piVal與 piCal指標所指 向的記憶體空間。 70
  • 71. 動態配置變數(3) 8-3 動態配置記憶體  程式範例:動態配置字串變數的宣告與應用範 例:CH08_20.c 71
  • 72. 8-3 動態配置記憶體  執行結果 72
  • 73. 8-3 動態配置記憶體  程式解說 第7行動態配置記憶與str1字串相同大小空間,而第 10行將str1字串複製到str2字串。 第13行輸出str2的位址與所指向的內容值。 第15行釋放str2字串記憶空間。 第13行輸出釋放後的str2位址與所指向的內容值。 73
  • 74. 8-3 動態配置記憶體 動態配置陣列(1)  動態配置一維陣列的方式如下,n=陣列長度: 資料型態* 指標名稱=(資料型態*)malloc(n*sizeof(資料型態));  當執行時期動態配置的一維陣列不需要時,可 以將其釋放,釋放動態配置的一維陣列的方式 如下: free(指標名稱); 74
  • 75. 動態配置陣列(2) 8-3 動態配置記憶體  程式範例:動態配置一維陣列的宣告與應用範 例:CH08_21.c 75
  • 77. 8-3 動態配置記憶體  執行結果 77
  • 78. 8-3 動態配置記憶體  程式解說 第10行請輸入欲產生的動態一維陣列個數,第11行 將整數指標指向動態配置一維陣列記憶空間。 第13~16行輸入max個數的陣列元素值。 第24行釋放指標指向的記憶空間。 78
  • 79. 8-4 上機實習課程 上機實習課程(1)  上機實習範例:CH08_22.c – 以下程式範例是利用指標常數方式來表示三維 陣列元素位址的方法與直接使用「&」取址運算 子取得三維陣列元素位址的比較。 – arr陣列元素內容如下: A[4][3][3]={{{1,-2,3},{4,5,-6},{8,9,2}}, {{7,-8,9},{10,11,12},{0.8,3,2}}, {{-13,14,15},{16,17,18},{3,6,7}}, {{19,20,21},{-22,23,24},(6-,9,12)}}; 79
  • 82. 8-4 上機實習課程  執行結果 82
  • 83. 8-4 上機實習課程 上機實習課程(2)  上機實習範例:CH08_23.c – 延續上題,以下程式範例是利用指標常數方式 來取得以下三維陣列arr的元數值,並計算每個 陣列元素值總和。 83
  • 84. 8-4 上機實習課程  執行結果 84
  • 85. 上機實習課程(3) 8-4 上機實習課程  上機實習範例:CH08_24.c – 以下程式範例中利用指標變數指向arr陣列,並 將此指標變數傳遞到計算次方值的cubic()函數, 再利用函數中的指標變數加法運算,來將每一 個元素值次方運算及所有新元素的總和。最後 再輸出所有新元素及總和。 85
  • 87. 8-4 上機實習課程  執行結果 87
  • 88. 8-4 上機實習課程 上機實習課程(4)  上機實習範例:CH08_25.c – 現在有三個整數陣列num1、num2、num3,其 中分別存放二位數整數、三位數整數與四位數 整數,如下所示: int num1[]={ 15,23,31 }; int num2[]={ 114,225,336 }; int num3[]={ 1237,3358,9271 }; – 請設計一程式,利用指標陣列的三個元素值指 向這三個陣列,並透過這個指標陣列來輸出此 三個整數陣列的所有元素值。 88
  • 90. 8-4 上機實習課程  執行結果 90
  • 91. 8-4 上機實習課程 上機實習課程(5)  上機實習範例:CH08_26.c – 以下程式範例只要是說明函數名稱本身也代表 了一個記憶體位址,當您呼叫函數時,其實就 是在告訴程式,執行該函數名稱所指向的記憶 體位址中之程式,這與函數後加上括號的呼叫 方式是有不同。 91
  • 92. 8-4 上機實習課程  執行結果 92
  • 93. 8-4 上機實習課程 上機實習課程(6)  上機實習範例:CH08_27.c – 延續上題的概念,函數名稱其實也是個指標變 數,其本身所儲存的值為函數內容所在的記憶 體起始位址,因此函數也可當成指標來宣告, 稱為「函式指標」。 – 其作用在於使用同一個函式指標名稱,主要作 用在於程式執行期間動態地決定該呼叫的函式。 宣告方式如下: 資料型態 (*ptr)(參數1, 參數2, …) 93
  • 95. 8-4 上機實習課程  執行結果 95
  • 96. 上機實習課程(7) 8-4 上機實習課程  上機實習範例:CH08_28.c – 請將一個整數指標變數指向二維陣列arr,並利 用指標運算將陣列中每一個元素值輸出。 – arr陣列內容如下: arr[4][3]={312,16,35,65,52,111,66,88,44,55,99,100}; 96
  • 97. 8-4 上機實習課程  執行結果 97
  • 98. 8-4 上機實習課程 上機實習課程(8)  上機實習範例:CH08_29.c – 請將一個字元指標變數指向由使用者輸入的字串, 並利用指標運算將字串中每一個字元輸出。 98
  • 99. 8-4 上機實習課程  執行結果 99
  • 100. 8-4 上機實習課程 上機實習課程(9)  上機實習範例:CH08_30.c – 請設計一函數replace(),可在使用者所輸入的 字串中指定位置及打算更換的字元,函數中將 使用字元指標來處理運算及置換過程。 100
  • 102. 8-4 上機實習課程  執行結果 102
  • 103. 上機實習課程(10) 8-4 上機實習課程  上機實習範例:CH08_31.c – 下面這個程式範例則是說明了三重指標的宣告 與使用方法,依據相同的方法也可以宣告更多 重指標。 103
  • 104. 8-4 上機實習課程  執行結果 104
  • 105. 8-4 上機實習課程 上機實習課程(11)  上機實習範例:CH08_32.c – 我們宣告一個指標變數p1並設定它的初值為指向 陣列變數array1的第五個元素的記憶體位址: int i,array1[5]={100,200,300,400,500}; int *p1=array1; p1=&array1[4]; – 例如當我們將指標變數p1減1之後,就是將目前指 標變數p1所指向的記憶體位址往前移動1次,也就 是指向陣列變數array1的第四個元素,請看以下 程式碼的實作驗證。 105
  • 107. 8-4 上機實習課程  執行結果 107
  • 108. 8-4 上機實習課程 上機實習課程(12)  上機實習範例:CH08_33.c – 以下程式範例是利用指標常數方式來表示三維 陣列元素位址的方法與直接使用「&」取址運算 子取得三維陣列元素位址的比較。 – arr陣列元素內容如下: A[4][3][3]={{{1,-2,3},{4,5,-6},{8,9,2}}, {{7,-8,9},{10,11,12},{8,3,2}}, {{-13,14,15},{16,17,18},{3,6,7}}, {{19,20,21},{-22,23,24},(-6,9,12)}}; 108
  • 111. 8-4 上機實習課程  執行結果 111
  • 112. 上機實習課程(13) 8-4 上機實習課程  上機實習範例:CH08_34.c – 以下程式範例是說明如果使用指標變數*ptr來存 取二維陣列中第i列的第j行元素可以利用如下公 式來取出該元素值: *(ptr+i*m+j); 112
  • 113. 8-4 上機實習課程  執行結果 113
  • 114. 上機實習課程(14) 8-4 上機實習課程  上機實習範例:CH08_35.c – 下面的範例程式以兩種不同方式建立字串,並利用 指標讀出其中的各個字元,顯示於螢幕中。 114
  • 115. 8-4 上機實習課程  執行結果 115
  • 116. 8-4 上機實習課程 上機實習課程(15)  上機實習範例:CH08_36.c – 以下程式範例是先取得使用者輸入字串,然後 比對是否和字串指標陣列中的某個字串相同。 116
  • 118. 8-4 上機實習課程  執行結果 118