| 特性 | 陣列 int a[2] | 指標 int *p |
| 本質 | 連續記憶體區塊(近似結構體) | 儲存地址的變數 |
sizeof | 8 bytes (2×4) | 4/8 bytes (指標大小) |
| 可修改性 | 不可修改基址 | 可指向任意位置 |
關鍵類型對照表
int a[10][20]; // 真正的二維陣列,連續記憶體 10×20×4 bytes
int *b[10]; // 指標陣列:10 個 int*,各自指向獨立記憶體
int (*p)[3]; // 陣列指標:指向「含 3 個 int 的陣列」
int (*p)(); // 函數指標:指向回傳 int 的函數
int *p(); // 函數宣告:回傳 int* 的函數
float **p; // 二級指標:指向指標的指標,非二維陣列
為何 float ** ≠ 二維陣列?
二維陣列 a[3][3] 記憶體佈局:
[a[0][0]] [a[0][1]] [a[0][2]] [a[1][0]] [a[1][1]] [a[1][2]] [a[2][0]] [a[2][1]] [a[2][2]]
↑ 基址連續 27 個 float
float **p 記憶體佈局:
p → [ptr0] → [row0: 3 floats]
[ptr1] → [row1: 3 floats]
[ptr2] → [row2: 3 floats]
↑ 間接存取,行記憶體可能不連續
結論:二維陣列是單一連續區塊;二級指標是指標陣列,每行獨立配置。
完整可執行範例:3×3 矩陣乘法
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void matrix_mult(float (*a)[3], float (*b)[3], float (*c)[3]);
void matrix_init(float (*a)[3]);
float a[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
float b[3][3] = {{2,3,4}, {5,6,7}, {8,9,1}};
float c[3][3] = {{0}};
int main() {
int i, j;
printf("原始陣列 A:\n");
for(i=0;i<3;i++) { for(j=0;j<3;j++) printf("%f ", a[i][j]); printf("\n"); }
printf("原始陣列 B:\n");
for(i=0;i<3;i++) { for(j=0;j<3;j++) printf("%f ", b[i][j]); printf("\n"); }
matrix_init(c);
matrix_mult(a, b, c);
printf("相乘後陣列 C:\n");
for(i=0;i<3;i++) { for(j=0;j<3;j++) printf("%f ", c[i][j]); printf("\n"); }
return 0;
}
void matrix_mult(float (*a)[3], float (*b)[3], float (*c)[3]) {
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c[i][j] += a[i][k] * b[k][j];
}
void matrix_init(float (*a)[3]) {
for(int i=2;i>=0;i--)
for(int j=2;j>=0;j--)
a[i][j] = 0;
}
通用解決方案總結
- 固定維度:
void func(int (*arr)[COLS]) — 最常用、效能最好
- 動態維度:
void func(int *arr, int rows, int cols) — 手動計算索引 arr[i*cols + j]
- 指標陣列:
void func(int **arr, int rows) — 需呼叫端建立指標陣列
- C99 VLA:
void func(int rows, int cols, int arr[rows][cols]) — 編譯器支援可變長度陣列
記憶體模型驗證
int a[10][20];
int *p = &a[0][0];
printf("%zu\n", sizeof(a)); // 800 (10*20*4)
printf("%zu\n", sizeof(p)); // 8 (64位系統指標大小)
這徹底證明:陣列名稱退化為指標時,僅保留基址資訊,型態資訊(維度)丟失,故函數參數必須顯式聲明第二維大小。
- 上一篇文章: 排序演算法詳解:選擇排序法
- 下一篇文章: C語言函數回傳陣列完整解析:記憶體模型與解決方案
Copyright ©
程式碼之家 All Rights Reserved