| 位置 | 內置類型 | 類類型 |
| 函數體外(全局/靜態) | 零初始化 | 默認構造函數 |
| 函數體內(局部) | 無初始化( indeterminate) | 默認構造函數 |
若類無默認構造函數,必須顯式初始化每個元素。
3. 顯式初始化語法
int a[3] = {1,2,3}; // 完全初始化
int b[5] = {1,2}; // 部分初始化,剩餘 0
int c[] = {1,2,3}; // 推導大小
int d[3] = {}; // C++11 全部 0
int e[3]{}; // C++11 統一初始化
// 錯誤:int f[3] = {1,2,3,4}; // 初始化器過多
4. 字符數組特例
char s1[] = {'c','+','+'}; // 長度 3,無結束符
char s2[] = {'c','+','+','\0'}; // 長度 4
char s3[] = "c++"; // 長度 4,自動添加 '\0'
char s4[4] = "c++"; // 合法
// 錯誤:char s5[3] = "c++"; // 空間不足(需 4)
字符串字面值長度 = 可見字符 + 1('\0')。
5. 禁止數組賦值與複製
int a[] = {1,2,3};
int b[] = a; // 錯誤:無法用數組初始化數組
int c[3]; c = a; // 錯誤:數組不可賦值
// 正確:用 vector 或 std::array
std::array arr = {1,2,3};
auto arr2 = arr; // 複製構造
arr2 = arr; // 賦值
6. 多維數組初始化
// 二維數組
int a[2][3] = {{1,2,3},{4,5,6}}; // 分行初始化
int b[2][3] = {1,2,3,4,5,6}; // 統一初始化(按行優先)
// 部分初始化
int c[2][3] = {{1},{4}}; // c[0]={1,0,0}, c[1]={4,0,0}
7. C# 對比(補充)
// C# 陣列初始化
string[] arr = new string[36];
for (int i=0; i<36; i++) arr[i] = "1";
// 或
var arr = Enumerable.Repeat("1", 36).ToArray();
8. 最佳實踐建議
- 優先使用
std::vector 或 std::array(C++11),避免原始數組陷阱。
- 必須用原始數組時:
- 定義時初始化:
int a[10] = {};
- 用
std::size(a) (C++17) 獲取長度,避免魔術數字。
- 傳遞給函數時退化為指針,同時傳遞長度,或用引用保持類型:
void f(int (&arr)[10])。
掌握數組初始化細節,能避免未定義行為,寫出更健壯的 C++ 代碼。現代 C++ 建議以容器代替原始數組。
- 上一篇文章: C 語言指針數組、數組指針、二維數組與數組名深度解析
- 下一篇文章: C++ 智能指針進階:unique_ptr/shared_ptr 構造差異、刪除器、第三方內存管理
Copyright ©
程式碼之家 All Rights Reserved