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

C語言深度解析:數組與指針的微妙關係

     編輯:關於C

在C語言編程中,數組看似簡單,實則暗藏玄機。早期寫代碼時,我習慣直接定義數組隨意使用,直到遇到棘手問題才發現:數組與指針的關係遠比想像中複雜。本文將通過實例深入剖析數組名、指針運算及sizeof運算符在不同語境下的行為差異。

核心問題:一個數組引發的指針迷宮

假設定義一個整型數組:int cc[10];

圍繞這個數組,衍生出多種指針表達式:cc、cc+1、&cc[0]、&cc、&cc+1。它們的含義各不相同,請先思考,再參考下面的測試代碼:

#include <stdio.h>
int main() {
    int cc[10];
    printf("%p\n", (void*)cc);
    printf("%p\n", (void*)(cc+1));
    printf("%p\n", (void*)&cc[0]);
    printf("%p\n", (void*)&cc);
    printf("%p\n", (void*)(&cc+1));
    getchar();
    return 0;
}

逐個擊破:五種表達式的真實含義

  • cc:數組名,在大多數表達式中自動轉換為指向首元素的指針(int*),值為首元素地址。
  • cc+1:指向第二個元素的指針,地址增加 sizeof(int) 字節(32位機上為4字節)。
  • &cc[0]:顯式取首元素地址,類型為 int*,值等同於 cc。
  • &cc:指向整個數組的指針,類型為 int (*)[10]。雖然數值上等於首地址,但語義完全不同——它代表數組整體。
  • &cc+1:指向數組末尾後一個位置的指針,地址增加 sizeof(cc)(即 40 字節),而非 4 字節。

內存佈局圖解

數組與指針內存佈局示意圖

圖中清晰展示:&cc 的類型是 int(*)[10],因此 &cc+1 跳過整個數組大小。這驗證了數組名不是普通指針,它是數組對象的標識符,是一個不可修改的左值。

關鍵規則:Array-to-Pointer 轉換

根據 C 標準,數組名只有在以下兩種情況下保持「數組類型左值」身份:

  1. 作為 sizeof 運算符的操作數
  2. 作為 & 取地址運算符的操作數

其餘所有場合,數組名自動退化為「指向首元素的指針常量」(右值)。這就是為什麼 sizeof(cc) 返回 40,而 sizeof(&cc) 卻返回 4(指針大小)。

實戰演練:sizeof 與指針運算

#include <stdio.h>
int main() {
    int cc[10];
    printf("%zu\n", sizeof(cc[0]));   // 4:單個 int 大小
    printf("%zu\n", sizeof(cc));      // 40:整個數組大小(10*4)
    printf("%zu\n", sizeof(&cc));     // 4:指向數組的指針大小
    printf("%zu\n", sizeof(int(*)[10])); // 4:同上
    getchar();
    return 0;
}

進階練習:指針數組 vs 數組指針

#include <stdio.h>
int main() {
    int *p[2];        // 指針數組:兩個 int* 元素
    printf("%p\n", (void*)*p);     // 未初始化,輸出隨機值
    printf("%zu\n", sizeof(p));    // 8:兩個指針大小 (2*4)
    printf("%zu\n", sizeof(&p));   // 4:指向指針數組的指針大小
    getchar();
    return 0;
}

字符串字面量的特殊性

#include <stdio.h>
int main() {
    char str[] = "hactrox";  // 棧上數組,包含結束符 '\0'
    char *p = str;           // 指向首字符
    printf("%zu %zu\n", sizeof(str), sizeof(p)); // 8, 4
    getchar();
    return 0;
}

str 是字符數組,sizeof(str) 計算包含 '\0' 在內的 8 字節;p 是指針,大小固定為 4 字節(32位)。

總結

數組與指針的區別是 C 語言進階的分水嶺。牢記:數組名本質是數組對象標識,僅在特定語境退化為指針。理解 &cc 的類型 int(*)[N],掌握 sizeof 的語境敏感性,才能避開指針運算的陷阱,寫出健壯高效的 C 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved