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

C語言數組與指標深度關聯:本質相同與訪問模式全解析

     編輯:關於C語言

核心真相:數組名即首元素地址

  • 數組名在絕大多數表達式中自動轉換為指向首元素的指標(&arr[0])。
  • 例外:sizeof(arr)、&arr、字符串字面量初始化時,數組名代表整個數組對象。

地址獲取等價性

char cs[] = "ABC";
printf("%p %p %p\n", cs, &cs[0], &cs);  // 三者數值相同,類型不同
// cs: char*      &cs[0]: char*      &cs: char(*)[4]

元素地址連續性

char cs[] = "ABC";
printf("%p\n%p\n%p\n%p\n", cs, &cs[0], &cs[1], &cs[2]);
// 輸出地址依次遞增 1 byte

指標訪問數組的多種模式

1. 指標變量遍歷(修改指標副本)

char *p = str;
for (int i = 0; i < len; i++) {
    printf("%c\n", *p);
    p++;  // 移動到下一元素
}

2. 指標算術不修改原指標

char *p = str;
for (int i = 0; i < len; i++)
    printf("%c\n", *(p + i));  // p 不變

3. 字符串以 '\0' 結束判斷

char *p = str;
while (*p != '\0') {
    printf("%c\n", *p++);
}

4. 整型數組指標遞增

int nums[] = {111,222,333,444};
int *p = nums;
for (int i = 0; i < 4; i++)
    printf("%d\n", *p++);  // 每次遞增 sizeof(int) 位元組

關鍵細節:指標運算按元素大小跳躍

int nums[] = {111,222,333,444};
int *p = nums;
printf("%d\n", *p);      // 111
printf("%d\n", *(p+1));  // 222 (地址 + sizeof(int))
printf("%d\n", *p+1);    // 112 (取值後 +1,非指標運算!)

p+1 ≠ 地址+1,而是 地址 + sizeof(*p)。這是指標運算的核心規則。

真正的數組指標 vs 元素指標

元素指標(最常用)

int *p = nums;  // 指向 int

數組指標(指向整個數組)


int nums[4] = {111,222,333,444};
int (*p)[4] = &nums;  // 注意括號優先級:指向含4個int數組的指標
printf("%d\n", (*p)[1]);  // 222,用法繁瑣

數組指標保留數組長度信息,sizeof(*p) 返回數組總大小,但使用麻煩,極少直接使用,多用於函數參數傳遞多維數組。

二維數組與指標


int arr[3][4];
int (*p)[4] = arr;      // arr 退化為指向首行的指標
int *p2 = &arr[0][0];   // 指向首個元素
// p+1 跳過一行 (4*sizeof(int)),p2+1 跳過一個元素

總結對比表

概念聲明指向算術步長典型用途
元素指標int *p單個元素sizeof(int)遍歷、函數參數
數組指標int (*p)[N]整個數組sizeof(int[N])多維數組參數
數組名int arr[N]首元素(多數情況)不可修改定義、sizeof、&arr

避坑指南

  1. 數組名不可賦值:arr = p; 錯誤,數組名非常量指標。
  2. 函數參數int arr[] 實為 int *arr,sizeof(arr) 返回指標大小。
  3. 指標減法結果為元素個數差(ptrdiff_t),非位元組差。
  4. 字符串字面量 "abc" 類型為 const char[4],賦值給 char* 違反 const(C++ 錯誤,C 警告)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved