一把梭系列 ~ 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) [指標與陣列]”
YOUTUBE URL: https://youtu.be/LweMpQSIZXc