C語言自學攻略-二維陣列與指標

更新於 發佈於 閱讀時間約 4 分鐘

前一章節講了許多,接下來要進入多維陣列了,不過相信你很快就能適應了。

簡單來說,int (*p)[MaxN] 是「指向一個含有 MaxNint 的陣列」的指標。

假設有一個二維陣列:

int arr[MaxM][MaxN];
  • arr 本身在某些表達上會轉換成 int (*)[MaxN],也就是指向 arr[0] (第一列)的指標。

現在若我們有:

int (*p)[MaxN];
p = arr; // p現在指向arr[0],也就是arr的第一列
  • p 的型別:int (*p)[MaxN]
    • 這表示 p 是一個指標,指向「包含 MaxNint的陣列」。
    • 當我們解參考 p 時,得到的是「int [MaxN]」型態的陣列,所以現在*p類似於一維陣列的名稱功能
  • p 是什麼?
    • p 目前可被視為 p 所指向的第一整列(row)。也就是 arr[0] 這個一維陣列(大小為 MaxN)。
    • p 解參考一次的話,上面說到*p類似於一維陣列的名稱功能。所以現在*p表示指向arr[0]這一陣列的第一個元素的位址。可以說是指到arr[0][0]這個位址。
  • (*p)[i]
    • (*p)[i] 表示從 p (也就是 arr[0]) 開始,取第 i 個元素。
    • 所以 (*p)[i] 等同於 arr[0][i] (為一個 int)。
  • 如果將 p 進行指標運算,如 p + 1
    • p + 1跳到下一列,也就是 arr[1]
    • 所以 (p + 1) 是 int (*)[MaxN] 型別的值,指向 arr[1]
    • (*(p + 1))[i] = arr[1][i]
  • **p :
    • 代表arr[0][0] 的內容
    • **(p+1) 代表arr[1][0] 的內容
    • *(*p+2)+1) 代表arr[2][1] 的內容

從上面我們還可以總結出,二維陣列名稱和名稱解參考一次都會輸出位址、而解參考兩次會輸出內容。

你可以這樣記: 要得到內容的話,幾維就解參考幾次

範例:

#include <stdio.h>

int main() {
const int MaxM = 3;
const int MaxN = 4;
int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

// p 是一個指標,指向一個擁有MaxN個int的陣列,即 p的型態為 int (*p)[MaxN]
int (*p)[MaxN] = arr; // 指向arr[0]這一行

// 現在 p 等同於 arr[0] (第一列)
// (*p)[0] = arr[0][0] = 1
// (*p)[1] = arr[0][1] = 2

printf("(*p)[0] = %d\n", (*p)[0]); // 輸出 1
printf("(*p)[1] = %d\n", (*p)[1]); // 輸出 2

// 將p往後移動一列
p = p + 1;
// 現在p指向arr[1]
// (*p)[0] = arr[1][0] = 5
// (*p)[1] = arr[1][1] = 6

printf("(*p)[0] = %d\n", (*p)[0]); // 輸出 5
printf("(*p)[1] = %d\n", (*p)[1]); // 輸出 6

// 我們也可以用迴圈走訪整個2維陣列
// 將p重新指回arr
p = arr;
for (int i = 0; i < MaxM; i++) {
for (int j = 0; j < MaxN; j++) {
// p+i 指向 arr[i], (* (p+i))[j] = arr[i][j]
printf("%d ", (*(p+i))[j]);
//printf("%d ", *(*(p+i)+j)); 相同效果
//printf("%d ", *(*(arr+i)+j)); 相同效果
//printf("%p ", *(p+i)+j); 相當於arr[i][j]的位址
}
printf("\n");
}

return 0;
}
  • 從上面的程式碼中,我們知道了各種方法去使用指標方式存取陣列。
在當今數位時代,電資領域人才需求爆發式成長,不論是前端網頁設計、嵌入式開發、人工智慧、物聯網還是軟硬體整合,這些技術都在改變世界。而掌握 C/C++、Python、數位邏輯、電路學與嵌入式開發等大學電資領域的課程,正是進入這個高薪、高需求產業的關鍵!
留言
avatar-img
留言分享你的想法!

































































這篇文章探討 C 語言中 sizeof 運算符在不同情況下的輸出結果,包括陣列、指標以及指標運算。文章詳細解釋了每個例子中 sizeof 運算符的行為,並說明瞭陣列名稱在不同語境下的含義。
本章將深入解析 C 語言的指標 (Pointers),這是 C 語言中最重要且強大的概念之一。指標能夠 直接操作記憶體位址,使程式具備更高的效能與靈活性,並廣泛應用於 陣列、函式、結構體與動態記憶體管理 等領域。
本章將介紹 C 語言的函式 (Functions),這是將程式碼模組化、提高可讀性與重用性 的關鍵技術。透過函式,我們可以 拆分程式邏輯、減少重複代碼,本章亦透過實作讓讀者學習 參數傳遞、回傳值、遞迴等重要觀念。
本章將介紹 C 語言的陣列 (Arrays),這是一種 連續儲存多個相同類型變數 的數據結構。透過陣列,我們可以有效管理與操作大量數據,並應用在 數據處理、排序、搜尋與多維數據存取 等情境中。
本章將介紹 C 語言的條件控制與迴圈控制,這是讓程式具備 邏輯判斷能力與重複執行能力 的關鍵技術。透過 if 判斷式、switch 多重選擇、for 迴圈、while 迴圈 等控制結構,我們可以有效管理程式流程,提升代碼的 效率與可讀性。
本章將介紹 C 語言的運算子 (Operators),這是程式語言的基礎,負責執行數值計算、條件判斷與邏輯運算。我們將最先學習變數在記憶體中的樣子,這是非常重要的觀念,接著漸入到算術運算、關係運算、邏輯運算、位元運算與三元運算子等,並透過 運算子優先順序 來確保正確的運算執行順序。
這篇文章探討 C 語言中 sizeof 運算符在不同情況下的輸出結果,包括陣列、指標以及指標運算。文章詳細解釋了每個例子中 sizeof 運算符的行為,並說明瞭陣列名稱在不同語境下的含義。
本章將深入解析 C 語言的指標 (Pointers),這是 C 語言中最重要且強大的概念之一。指標能夠 直接操作記憶體位址,使程式具備更高的效能與靈活性,並廣泛應用於 陣列、函式、結構體與動態記憶體管理 等領域。
本章將介紹 C 語言的函式 (Functions),這是將程式碼模組化、提高可讀性與重用性 的關鍵技術。透過函式,我們可以 拆分程式邏輯、減少重複代碼,本章亦透過實作讓讀者學習 參數傳遞、回傳值、遞迴等重要觀念。
本章將介紹 C 語言的陣列 (Arrays),這是一種 連續儲存多個相同類型變數 的數據結構。透過陣列,我們可以有效管理與操作大量數據,並應用在 數據處理、排序、搜尋與多維數據存取 等情境中。
本章將介紹 C 語言的條件控制與迴圈控制,這是讓程式具備 邏輯判斷能力與重複執行能力 的關鍵技術。透過 if 判斷式、switch 多重選擇、for 迴圈、while 迴圈 等控制結構,我們可以有效管理程式流程,提升代碼的 效率與可讀性。
本章將介紹 C 語言的運算子 (Operators),這是程式語言的基礎,負責執行數值計算、條件判斷與邏輯運算。我們將最先學習變數在記憶體中的樣子,這是非常重要的觀念,接著漸入到算術運算、關係運算、邏輯運算、位元運算與三元運算子等,並透過 運算子優先順序 來確保正確的運算執行順序。
你可能也想看
Google News 追蹤