首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

深入理解C指針(四):指針與陣列的微妙關係

     編輯:關於C語言

深入理解C指針(四):指針與陣列的微妙關係

《深入理解C指針》第四章學習筆記。指針與陣列是C語言最核心也最易混淆的概念,二者既有相似性又有本質區別。

一、相同點:都代表地址

int arr[10];     // arr 是首元素地址(常量指針)
int *p = malloc(10 * sizeof(int)); // p 指向堆上首地址(變量指針)
  • arr 和 p 在表達式中均轉換為首元素地址
  • 均可用下標訪問:arr[i] ≡ *(arr+i),p[i] ≡ *(p+i)

二、關鍵區別

三、指針陣列 vs 二維陣列

// 指針陣列:每個元素是指針
int *ptr_arr[5] = {&a, &b, &c, &d, &e};
printf("%d", *ptr_arr[i]);  // 需解引用

// 二維陣列:連續內存塊
int matrix[3][4];
printf("%d", matrix[i][j]); // 編譯器計算偏移:i*4+j

四、動態分配陣列

// 一維動態陣列
int *p = malloc(5 * sizeof(int));
for (int i = 0; i < 5; i++) p[i] = i + 1;

// 指針陣列動態分配(鋸齒陣列)
int **jagged = malloc(5 * sizeof(int*));
for (int i = 0; i < 5; i++) {
    jagged[i] = malloc(sizeof(int));
    *jagged[i] = i;
}

// 二維動態陣列(連續內存)
int rows = 3, cols = 4;
int **mat = malloc(rows * sizeof(int*));
mat[0] = malloc(rows * cols * sizeof(int)); // 一塊連續內存
for (int i = 1; i < rows; i++) mat[i] = mat[0] + i * cols;

五、二維陣列作函數參數

子函數無法直接用 arr[i][j],需退化為一維指針並手動計算偏移:

void init(int *arr, int rows, int cols) {
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < cols; j++)
            *(arr + i * cols + j) = ...;  // 手動偏移
}

int main() {
    int a[5][6];
    init(&a[0][0], 5, 6);  // 傳首元素地址
}

六、經典代碼示例

// 指針陣列遍歷
int *num1[3];
int num2[3] = {1, 2, 3};
for (int i = 0; i < 3; i++) num1[i] = &num2[i];
for (int i = 0; i < 3; i++) printf("%4d", *num1[i]);

// 二維陣列統一初始化/打印
void arr_init(int *arr, int rows, int cols) { ... }
void arr_print(int *arr, int rows, int cols) { ... }

int main() {
    int n1[5][6], n2[7][8];
    arr_init(&n1[0][0], 5, 6);
    arr_print(&n1[0][0], 5, 6);
    arr_init(&n2[0][0], 7, 8);
    arr_print(&n2[0][0], 7, 8);
}

七、核心心法

  1. 陣列名不是指針,只是在大多數表達式中「退化」為首元素指針
  2. sizeof 是編譯時運算符,能分辨陣列與指針
  3. 函數參數退化:void f(int a[]) 等價於 void f(int *a)
  4. 動態分配二維陣列:首選「指針陣列+連續數據塊」模式,兼顧 arr[i][j] 語法與內存連續性

指針與陣列的區別是C語言進階的分水嶺,徹底理解內存模型、類型系統與編譯器行為,方能寫出健壯高效的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性陣列名 (arr)指針變量 (p)
存儲位置棧區(靜態分配)指針變量在棧,指向堆/棧/數據區
可修改性常量,不可賦值/自增變量,可指向任意合法地址
sizeof 結果整個陣列大小(字節數)指針大小(4/8字節)
類型int [10] → 退化為 int*int*