一把梭系列 ~ C語言範例 (0017) [指標與陣列]

一把梭系列 ~ C語言範例 (0017) [指標與陣列]

一把梭系列 ~ C語言範例 (0017) [指標與陣列]


資料來源: https://openhome.cc/Gossip/CGossip/PointerAndArray.html

https://openhome.cc/Gossip/CGossip/Pointer2Pointer.html

線上執行: https://www.tutorialspoint.com/compile_c_online.php


★前言:


★主題:

    01.陣列是一塊連續且分割好的記憶體空間,在宣告陣列之後,使用到陣列變數時,會取得首元素的位址,例如在下面的程式中將指出,陣列 arr 與 &arr[0]

    int arr[10] = {0};

    printf("arr :\t\t%p\n", arr);
    printf("&arr[0] :\t%p\n", &arr[0]); 


    02.陣列索引其實是相對於首元素位址的位移量,下面這個程式以指標運算與陣列索引操作,顯示出相同的對應位址值

    int arr[10] = {0};
    int *p = arr;

    for(int i = 0; i < LEN; i++) {
        printf("&arr[%d]: %p", i ,&arr[i]);
        printf("\t\tptr + %d: %p\n", i, p + i);
    }


    03.利用指標運算來取出陣列的元素值

    int arr[5] = {10, 20, 30, 40, 50};
    int *p = arr;


    for(int i = 0; i < 5; i++) {
        printf("*(p + %d): %d\n", i , *(p + i));
    }
    putchar('\n');

    for(int i = 0; i < 5; i++) {
        printf("*(arr + %d): %d\n", i , *(arr + i));
    }


    04.使用指標計算陣列大小

    int arr[] = {10, 20, 30, 40, 50}; 
 
    int len = *(&arr + 1) - arr;// sizeof(arr)/sizeof(int);
    //每個陣列元素的位址型態是 int*,這表示對它進行運算時,是以 int 長度為單位,而 arr 變數的位址處就是陣列資料的開端,&arr 型態會是…呃…int (*)[5],5 是陣列長度
    //int (*)[5] 表示,對它進行運算時,是以 5 個 int 長度為單位,因此 &arr + 1 的結果,會是陣列使用的空間後之位址,而 *(&arr + 1) 的值型態會回到 int*,也就是最後一個元素後之位址,這時就可以與 int* 的 arr 進行相減,也就是與第一個元素之位址相減,就可以得到陣列長度了
    int *begin = arr;
    int *end = *(&arr + 1);
    printf("%d\n", end - begin);


    05.二維陣列計算行與列

    int maze[ROWS][LEN] = {
                                {1, 2, 3},
                                {4, 5, 6}
                          };

    printf("ROWS: %d\n", *(&maze + 1) - maze);
    printf("LEN: %d\n", *(&maze[0] + 1) - maze[0]); 


    06.二維陣列使用一維指標存取

    int maze[ROWS][LEN] = {
                                {1, 2, 3},
                                {4, 5, 6}
                          };
   
    for(int i = 0; i < ROWS; i++)
    {
        int *row = maze[i];
        for(int j = 0; j < LEN; j++) 
        {
            printf("%d\t", row[j]); 
        } 
    }


    07.一維陣列轉存二維陣列

    int row1[LEN] = {1, 2, 3};
    int row2[LEN] = {4, 5, 6};
    int* maze[ROWS] = {row1, row2};

    for(int i = 0; i < ROWS; i++) {
        int *row = maze[i];
        for(int j = 0; j < LEN; j++) {
            printf("%d\t", row[j]); 
        }
        printf("\n");
    }


★code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i=0,j=0;
    int arr[10] = {0};

    //陣列是一塊連續分割好的記憶體空間,在宣告陣列之後,使用到陣列變數時,會取得首元素的位址,例如在下面的程式中將指出,陣列 arr 與 &arr[0]
    printf("arr :\t\t%p\n", arr);
    printf("&arr[0] :\t%p\n\n", &arr[0]);

    //陣列索引其實是相對於首元素位址的位移量,下面這個程式以指標運算與陣列索引操作,顯示出相同的對應位址值
    int *p = arr;
    for(i = 0; i < 10; i++) {
        printf("&arr[%d]: %p", i ,&arr[i]);
        printf("\t\tptr + %d: %p\n", i, p + i);
    }
    printf("\n");

    //利用指標運算來取出陣列的元素值
    int arr01[5] = {10, 20, 30, 40, 50};
    p = arr01;

    for(i = 0; i < 5; i++) {
        printf("*(p + %d): %d\n", i , *(p + i));
    }
    printf("\n");

    for(i = 0; i < 5; i++) {
        printf("*(arr01 + %d): %d\n", i , *(arr01 + i));
    }
    printf("\n");

    //使用指標計算陣列大小
	//每個陣列元素的位址型態是 int*,這表示對它進行運算時,是以 int 長度為單位,而 arr 變數的位址處就是陣列資料的開端,&arr 型態會是…呃…int (*)[5],5 是陣列長度
	//int (*)[5] 表示,對它進行運算時,是以 5 個 int 長度為單位,因此 &arr + 1 的結果,會是陣列使用的空間後之位址,而 *(&arr + 1) 的值型態會回到 int*,也就是最後一個元素後之位址,這時就可以與 int* 的 arr 進行相減,也就是與第一個元素之位址相減,就可以得到陣列長度了
	int len = *(&arr01 + 1) - arr01;// sizeof(arr)/sizeof(int);

	int *begin01 = arr;
	int *end01 = *(&arr + 1);

	printf("arr size:%d\n", end01 - begin01);
	printf("arr01 size:%d\n\n",len);

    //二維陣列計算行與列
    int maze[2][3] = {
                        {1, 2, 3},
                        {4, 5, 6}
                     };

    printf("ROWS: %d\n", *(&maze + 1) - maze);
    printf("COLs: %d\n\n", *(&maze[0] + 1) - maze[0]);

    //二維陣列使用一維指標存取
    for(i = 0; i < 2; i++)
    {
        int *row = maze[i];
        for(j = 0; j < 3; j++)
        {
            printf("%d\t", row[j]);
        }
    }
    printf("\n\n");

    //一維陣列轉存二維陣列
    int row1[3] = {1, 2, 3};
    int row2[3] = {4, 5, 6};
    int* maze01[2] = {row1, row2};

    for(i = 0; i < 2; i++) {
        int *row = maze01[i];
        for(j = 0; j < 3; j++) {
            printf("%d\t", row[j]);
        }
        printf("\n");
    }

    return 0;
}


★結果:


★延伸說明/重點回顧:

    01.陣列是一塊連續且分割好的記憶體空間

    02.C/C++ 可以利用指標運算來取出陣列的元素值

    03.C/C++ 可以利用指標計算出陣列大小

    04.C/C++ 二維陣列可以使用一維指標存取

    05.C/C++ 一維陣列可以轉存二維陣列

One thought on “一把梭系列 ~ C語言範例 (0017) [指標與陣列]

jash.liao@qq.com 發表迴響 取消回覆

你的電子郵件位址並不會被公開。 必要欄位標記為 *