
- C程式設計教程
- C - 首頁
- C語言基礎
- C - 概述
- C - 特性
- C - 歷史
- C - 環境設定
- C - 程式結構
- C - Hello World
- C - 編譯過程
- C - 註釋
- C - 詞法單元
- C - 關鍵字
- C - 識別符號
- C - 使用者輸入
- C - 基本語法
- C - 資料型別
- C - 變數
- C - 整數提升
- C - 型別轉換
- C - 型別強制轉換
- C - 布林值
- C語言中的常量和字面量
- C - 常量
- C - 字面量
- C - 轉義序列
- C - 格式說明符
- C語言中的運算子
- C - 運算子
- C - 算術運算子
- C - 關係運算符
- C - 邏輯運算子
- C - 位運算子
- C - 賦值運算子
- C - 一元運算子
- C - 自增和自減運算子
- C - 三元運算子
- C - sizeof 運算子
- C - 運算子優先順序
- C - 其他運算子
- C語言中的決策
- C - 決策
- C - if 語句
- C - if...else 語句
- C - 巢狀 if 語句
- C - switch 語句
- C - 巢狀 switch 語句
- C語言中的迴圈
- C - 迴圈
- C - while 迴圈
- C - for 迴圈
- C - do...while 迴圈
- C - 巢狀迴圈
- C - 無限迴圈
- C - break 語句
- C - continue 語句
- C - goto 語句
- C語言中的函式
- C - 函式
- C - 主函式
- C - 按值呼叫函式
- C - 按引用呼叫函式
- C - 巢狀函式
- C - 可變引數函式
- C - 使用者自定義函式
- C - 回撥函式
- C - 返回語句
- C - 遞迴
- C語言中的作用域規則
- C - 作用域規則
- C - 靜態變數
- C - 全域性變數
- C語言中的陣列
- C - 陣列
- C - 陣列的特性
- C - 多維陣列
- C - 將陣列傳遞給函式
- C - 從函式返回陣列
- C - 可變長陣列
- C語言中的指標
- C - 指標
- C - 指標和陣列
- C - 指標的應用
- C - 指標運算
- C - 指標陣列
- C - 指向指標的指標
- C - 將指標傳遞給函式
- C - 從函式返回指標
- C - 函式指標
- C - 指向陣列的指標
- C - 指向結構體的指標
- C - 指標鏈
- C - 指標與陣列
- C - 字元指標和函式
- C - 空指標
- C - void 指標
- C - 懸空指標
- C - 解引用指標
- C - 近、遠和巨型指標
- C - 指標陣列的初始化
- C - 指標與多維陣列
- C語言中的字串
- C - 字串
- C - 字串陣列
- C - 特殊字元
- C語言中的結構體和聯合體
- C - 結構體
- C - 結構體和函式
- C - 結構體陣列
- C - 自引用結構體
- C - 查詢表
- C - 點 (.) 運算子
- C - 列舉 (或 enum)
- C - 結構體填充和打包
- C - 巢狀結構體
- C - 匿名結構體和聯合體
- C - 聯合體
- C - 位域
- C - Typedef
- C語言中的檔案處理
- C - 輸入 & 輸出
- C - 檔案 I/O (檔案處理)
- C預處理器
- C - 預處理器
- C - 指令
- C - 預處理器運算子
- C - 宏
- C - 標頭檔案
- C語言中的記憶體管理
- C - 記憶體管理
- C - 記憶體地址
- C - 儲存類
- 其他主題
- C - 錯誤處理
- C - 可變引數
- C - 命令執行
- C - 數學函式
- C - static 關鍵字
- C - 隨機數生成
- C - 命令列引數
- C程式設計資源
- C - 問答
- C - 快速指南
- C - 速查表
- C - 有用資源
- C - 討論
C語言中的指標和多維陣列
在 C 語言中,陣列是儲存在連續記憶體位置中的一組相同型別的值的集合。陣列(一維或多維)中的每個元素都由一個或多個唯一的整數索引標識。
另一方面,指標儲存變數的地址。陣列中第 0 個元素的地址是陣列的指標。您可以使用“解引用運算子”訪問指標指向的值。
您可以在 C 中宣告一維、二維或多維陣列。“維度”一詞指的是識別集合中元素所需的索引數。
指標和一維陣列
在一維陣列中,每個元素都由一個整數標識
int a[5] = {1, 2, 3, 4, 5};
這裡,數字“1”位於索引 0 處,“2”位於索引 1 處,依此類推。
儲存第 0 個元素地址的變數是它的指標 -
int *x = &a[0];
簡單來說,陣列的名稱也指向第 0 個元素的地址。因此,您還可以使用此表示式 -
int *x = a;
示例
由於指標的值會根據資料型別的尺寸遞增,“x++”會將指標移動到陣列中的下一個元素。
#include <stdio.h> int main(){ int arr[] = {1, 2, 3, 4, 5}; int length = sizeof(arr) / sizeof(arr[0]); int i = 0; int *ptr = arr; while (i < length){ printf("arr[%d]: %d \n", i, *(ptr + i)); i++; } return 0; }
輸出
執行此程式碼時,將產生以下輸出 -
arr[0]: 1 arr[1]: 2 arr[2]: 3 arr[3]: 4 arr[4]: 5
指標和二維陣列
如果一維陣列類似於元素列表,則二維陣列類似於表格或矩陣。
二維陣列中的元素可以被認為是在邏輯上以行和列排列的。因此,任何元素的位置都由兩個索引決定,即它的行號和列號。行索引和列索引都從“0”開始。
int arr[2][2];
這樣的陣列表示為 -
Col0 | Col1 | Col2 | |
---|---|---|---|
Row0 | arr[0][0] | arr[0][1] | arr[0][2] |
Row1 | arr[1][0] | arr[1][1] | arr[1][2] |
Row2 | arr[2][0] | arr[2][1] | arr[2][2] |
需要注意的是,表格排列僅是一種邏輯表示。編譯器分配一塊連續的位元組。在 C 中,陣列分配以行優先的方式進行,這意味著元素以行方式讀入陣列。
這裡,我們宣告一個具有三行四列的二維陣列(第一個方括號中的數字始終指代行數)如下 -
int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} };
編譯器將以行優先的順序為上述二維陣列分配記憶體。假設陣列的第一個元素位於地址 1000 處,並且型別“int”的大小為 4 位元組,則陣列的元素將獲得以下分配的記憶體位置 -
Row 0 | Row 1 | Row 2 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
值 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
地址 | 1000 | 1004 | 1008 | 1012 | 1016 | 1020 | 1024 | 1028 | 1032 | 1036 | 1040 | 1044 |
我們將使用地址 & 運算子將陣列 num 的第一個元素的地址分配給指標 ptr。
int *ptr = &arr[0][0];
示例 1
如果指標遞增 1,它將移動到下一個地址。“3×4”陣列中的所有 12 個元素都可以在迴圈中訪問,如下所示 -
#include <stdio.h> int main(){ int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, }; // pointer ptr pointing at array num int *ptr = &arr[0][0]; int i, j, k = 0; // print the elements of the array num via pointer ptr for (i = 0; i < 3; i++){ for (j = 0; j < 4; j++){ printf("%d ", *(ptr + k)); k++; } printf("\n"); } return 0; }
輸出
執行此程式碼時,將產生以下輸出 -
1 2 3 4 5 6 7 8 9 10 11 12
通常,可以使用以下公式獲得陣列中任何元素的地址 -
add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]
在我們的 3×4 陣列中,
add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044
您可以參考上圖,它確認“arr[3][4]”的地址是 1044。
示例 2
使用解引用指標獲取地址處的值。讓我們使用此公式在指標的幫助下遍歷陣列 -
#include <stdio.h> int main(){ // 2d array int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; int ROWS = 3, COLS = 4; int i, j; // pointer int *ptr = &arr[0][0]; // print the element of the array via pointer ptr for (i = 0; i < ROWS; i++){ for (j = 0; j < COLS; j++) { printf("%4d ",*(ptr + (i * COLS + j))); } printf("\n"); } return 0; }
輸出
執行此程式碼時,將產生以下輸出 -
1 2 3 4 5 6 7 8 9 10 11 12
指標和三維陣列
三維陣列是二維陣列的陣列。此類陣列用三個下標宣告 -
int arr [x] [y] [j];
此陣列可以被視為“x”個層的表格,每個表格具有“x”行和“y”列。
三維陣列的一個示例是 -
int arr[3][3][3] ={ { {11, 12, 13}, {14, 15, 16}, {17, 18, 19} }, { {21, 22, 23}, {24, 25, 26}, {27, 28, 29} }, { {31, 32, 33}, {34, 35, 36}, {37, 38, 39} }, };
指向三維陣列的指標可以宣告為 -
int * ptr = &arr[0][0][0];
知道陣列的名稱本身就是第 0 個元素的地址,我們可以將三維陣列的指標寫為 -
int * ptr = arr;
“x”行和“y”列的每一層佔用 -
x * y * sizeof(data_type)
位元組數。假設分配給上面宣告的三維陣列“arr”的記憶體從地址 1000 開始,則第二層(i = 1)從 1000 + (3 × 3) × 4 = 1036 位元組位置開始。
ptr = Base address of 3D array arr
如果 JMAX 是行數,KMAX 是列數,則第 1 個切片的第 0 行和第 0 列的元素的地址為 -
arr[1][0][0] = ptr + (1 * JMAX * KMAX)
獲取第 i 個切片的第 j 行和第 k 列的元素值的公式可以給出如下 -
arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))
示例:使用指標解引用列印三維陣列
讓我們使用此公式在指標解引用的幫助下列印三維陣列 -
#include <stdio.h> int main(){ int i, j, k; int arr[3][3][3] = { { {11, 12, 13}, {14, 15, 16}, {17, 18, 19} }, { {21, 22, 23}, {24, 25, 26}, {27, 28, 29} }, { {31, 32, 33}, {34, 35, 36}, {37, 38, 39} }, }; int JMAX = 3, KMAX = 3; int *ptr = arr; // &arr[0][0][0]; for(i = 0; i < 3; i++){ for(j = 0; j < 3; j++){ for(k = 0; k < 3; k++){ printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k))); } printf("\n"); } printf("\n"); } return 0; }
輸出
執行此程式碼時,將產生以下輸出 -
11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39
通常,使用指標訪問陣列與使用下標表示訪問陣列非常相似。兩者之間的主要區別在於,陣列的下標宣告以靜態方式分配記憶體,而我們可以使用指標進行動態記憶體分配。
要將多維陣列傳遞給函式,您需要使用指標而不是下標。但是,使用下標陣列比使用指標更方便,對於初學者來說可能比較困難。