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

C/C++ 數組聲明完全指南:從參數傳遞到 sizeof 陷阱

     編輯:關於C

前言:從 Java/.NET 轉 C/C++ 的「數組文化衝擊」

習慣了 Java int[] arr 或 C# int[] arr 的開發者,初次接觸 C/C++ 數組時常會困惑:為什麼數組名有時是指標、有時又不是?為什麼 int* a = {1,2} 編譯報錯?本文系統梳理數組聲明、參數傳遞、初始化與 sizeof 的核心規則。

一、函數參數:兩種寫法本質相同

[cpp]
int FindMax1(int* Array);   // 寫法 1:顯式指標
int FindMax2(int Array[]);  // 寫法 2:數組語法糖

結論:在函數參數列表中,int Array[] 會被編譯器自動轉換為 int* Array。兩者語義完全等價,都是傳遞首元素地址,**數組長度信息丟失**,函數內無法通過 sizeof 獲取元素個數。

二、定義與初始化:指標 ≠ 數組

[cpp]
// 錯誤:指標無法直接用列表初始化
int* Array1 = {0, 1, 2, 3};  // 編譯失敗

// 正確:數組定義可用列表初始化
int Array2[] = {0, 1, 2, 3}; // 編譯通過,長度自動推導為 4

核心區別:

  • int* p:聲明一個指標變量,需單獨分配內存(malloc/new)或指向現有對象。
  • int a[]:聲明一個數組對象,編譯器自動分配連續內存,大小由初始化列表或显式長度決定。

初始化最佳實踐

[cpp]
int a1[10] = {0};           // 全部置 0,C 標準保證未列出元素零初始化
char a2[] = {'a','b','c',0};// 未指定長度,由列表元素數決定(此處為 4)
int a3[8] = {1,2,3,4};      // 長度 8,前 4 個顯式初始化,後 4 個自動補 0
// 等價於 int a3[8] = {1,2,3,4,0,0,0,0};

效率提示:使用 int a[] = {...} 列表初始化比逐元素賦值更高效,編譯器可生成批量內存初始化指令。

三、sizeof 陷阱:指標 vs 數組

[cpp]
int* p = malloc(10 * sizeof(int));
int arr[10] = {0};

sizeof(p);    // 4 (32位) 或 8 (64位) —— 指標變量本身的大小
sizeof(arr);  // 40 —— 數組佔用的總字節數 (10 * sizeof(int))

口訣:sizeof(數組名) 只有在**數組定義的作用域內**才代表整個數組大小;一旦作為參數傳遞或賦值給指標,即退化為指標,sizeof 返回指標大小。

四、總結速查表

場景語法語義關鍵點
函數參數int* a / int a[]指向首元素的指標長度信息丟失,需額外傳遞 size
定義+初始化int a[] = {...}數組對象,自動推導長度推薦寫法,高效且安全
定義+指定長度int a[N] = {...}固定長度數組列表較短時餘下元素零初始化
動態分配int* a = malloc(N*sizeof(int))堆上連續內存,需手動 free本質是指標,非數組
sizeof 計算sizeof(arr)整個數組字節數僅在定義作用域有效

避坑指南

  1. **永遠不要**用 sizeof(指標) 計算動態分配的元素個數。
  2. 函數接收數組時,**同時傳遞長度參數** 或使用哨兵值(如字符串的 \0)。
  3. 現代 C++ (C++11+) 建議優先使用 std::vector / std::array / std::span,彻底规避原始数组陷阱。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved