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

C++ 陣列名本質深度解析:三個結論與四個陷阱

     編輯:關於C++

三大核心結論

  1. 內涵:陣列名代表一種資料結構——陣列本身。
  2. 外延:可轉換為指向該陣列的指標常量(不可修改指向)。
  3. 指向陣列的指標:獨立變數類型 (Win32 下 4 位元組),僅保存陣列起始地址,不含資料結構內涵。

結論 1 驗證:sizeof 見真章

char str[10] = "I Love U";
sizeof(str);  // 10 (陣列大小),非 4/8

int intArray[10];
sizeof(intArray);  // 40 (10 * sizeof(int))

若 C++ 支援 int[10] intArray; 語法,本質更清晰:intArray 為 int[10] 型別的實例。

結論 2 驗證:隱性轉換為指標常量

char* p = str;      // 合法:陣列名 → 指標常量
str++;              // 編譯錯誤:常量不可修改
void foo(char s[]); // 形參實為 char*
foo(str);           // 合法:傳遞指標常量值

結論 3:sizeof 是運算子非函式

sizeof(int);  // 合法:運算子接受型別運算元,函式不可

陷阱 1:函式參數喪失內涵與常量性

void arrayTest(char str[]) {
    sizeof(str);  // 4/8 (指標大小)!非 10
    str++;        // 合法!形參實為普通指標,非常量
}

結論 4:陣列名作函式形參時,全面淪為普通指標——失去資料結構內涵、失去常量性、失去大小資訊。

陷阱 2:多維陣列退化規則

int a[3][4];
sizeof(a);        // 48 (3*4*4)
void foo(int a[][4]); // 形參為 int (*)[4],保留次維大小
// 僅第一維退化為指標

陷阱 3:&陣列名 型別不同

int a[10];
a;        // int* (轉換後)
&a;       // int (*)[10] (陣列指標),指向整個陣列
&a + 1;   // 跨越整個陣列 (40 bytes),而非單一 int

陷阱 4:字串字面值 vs 字元陣列


char str[] = "hello";  // 陣列,大小 6,可修改
char* p = "hello";     // 指向唯讀區字面值,不可修改
sizeof(str); // 6
sizeof(p);   // 4/8

現代 C++ 替代方案

  • std::array<T, N>:保留大小、支援值語意、無退化。
  • std::span<T> (C++20):非擁有視圖、攜帶大小、替代指標+長度組合。
  • 範圍 for:自動處理邊界,消除手動索引錯誤。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved