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

C 語言陣列下標與指標關係深度解析:a[i] 等價 *(a+i)、指標算術、陣列退化

     編輯:C 語言問答

核心等價關係


int a[5] = {10, 20, 30, 40, 50};
// 以下四種寫法完全等價,生成相同機器碼:
a[i]        // 下標語法糖
*(a + i)    // 指標算術:a 退化為指向首元素指標,+i 位移 i 個 int
*(i + a)    // 加法交換律,同樣合法
i[a]        // 同樣合法!*(i+a) → a[i],C 允許此寫法 (但請勿實際使用)

標準定義 (C99 6.5.2.1)

a[b] **定義為** *(a + b)。其中 a 為指標表達式,b 為整數表達式。

陣列名 a 的雙重身分

場合表現型別
**sizeof(a)**整個陣列大小 (如 5*4=20 位元組)int [5]
**&a**陣列首地址,**型別為指向整個陣列的指標**int (*)[5]
**其他場合** (傳參、賦值、運算)**退化** 為指向首元素的指標int *

退化後失去長度資訊


void func(int arr[]) {          // 等價 int *arr
    printf("%zu\n", sizeof(arr)); // 輸出 8 (64位指標大小),非陣列大小
}
int a[100];
func(a); // a 退化為 int*,長度 100 丟失

**對策**:函數參數同時傳遞長度 void func(int *arr, size_t n),或用結構體封裝 struct { int *data; size_t len; }。

指標 vs 陣列:本質差異

特性陣列 int a[10]指標 int *p
記憶體分配編譯期靜態/棧上連續 10*sizeof(int)僅儲存位址 (8 位元組),指向資料需另行分配
可修改指向不可 (a 是常量指標,非左值)可 (p = malloc(...); p++)
sizeof整個陣列大小指標大小 (4/8 位元組)
初始化int a[] = {1,2,3};int *p = malloc(...); 或指向現有物件
字串字面量char s[] = "abc"; 可修改char *p = "abc"; 指向唯讀區,**不可修改**

指標算術與下標互換實例


// 字串長度 (不呼叫 strlen)
size_t my_strlen(const char *s) {
    const char *p = s;
    while (*p) p++;
    return p - s; // 指標相減得元素個數
}

// 反轉字串 (雙指標)
void reverse(char *s) {
    char *left = s, *right = s;
    while (*right) right++; // 移至 \0
    right--; // 最後一個字元
    while (left < right) {
        char tmp = *left;
        *left++ = *right;
        *right-- = tmp;
    }
}

避坑指南

  1. int *p = a; 後 p++ 合法,a++ **非法** (陣列名非左值)。
  2. 函數參數 int a[]、**永遠視為 int *a**,sizeof(a) 在函數內**不可用**取陣列長度。
  3. char *p = "literal"; → p[0] = 'x'; **未定義行為** (寫入唯讀記憶體)。正確:char s[] = "literal";。
  4. 動態陣列:int *arr = malloc(n * sizeof(int)); 用完 free(arr);,arr = NULL;。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved