在C++中,數組是存儲固定大小同類型元素的連續內存塊。它是最基礎的數據結構之一,廣泛用于各種場景。以下是關于數組的詳細介紹:
一、一維數組
1. 定義與初始化
- 語法:
類型 數組名[元素個數];
- 示例:
int arr[5]; // 定義包含5個整數的數組 arr[0] = 10; // 賦值 arr[1] = 20;// 初始化列表 int arr2[5] = {1, 2, 3, 4, 5}; // 完整初始化 int arr3[] = {10, 20, 30}; // 自動推導長度為3 int arr4[5] = {1, 2}; // 部分初始化,剩余元素為0
2. 訪問與遍歷
- 下標訪問:索引從0開始,范圍為
0
到長度-1
。int value = arr[2]; // 訪問第3個元素 arr[3] = 40; // 修改第4個元素
- 遍歷方式:
// 傳統for循環 for (int i = 0; i < 5; i++) {cout << arr[i] << " "; }// 范圍for循環(C++11起) for (int num : arr) {cout << num << " "; }
二、多維數組
1. 二維數組
- 定義:
類型 數組名[行數][列數];
- 示例:
int matrix[2][3] = {{1, 2, 3},{4, 5, 6} };// 訪問元素 int value = matrix[1][2]; // 第二行第三列(值為6)
2. 多維數組內存布局
- 連續存儲:多維數組在內存中按行優先(Row-major)存儲,例如:
int arr[2][2] = {{1, 2}, {3, 4}}; // 內存布局:1, 2, 3, 4
三、數組與指針
1. 數組名隱式轉換為指針
- 數組名在多數表達式中會隱式轉換為指向首元素的指針:
int arr[5] = {1, 2, 3, 4, 5}; int* ptr = arr; // 等價于 &arr[0]// 通過指針訪問數組 cout << *ptr; // 輸出1 cout << *(ptr+2); // 輸出3(等價于 arr[2])
2. 指針算術
- 指針加減運算基于元素類型大小:
int* p = arr; p++; // 指針移動4字節(int類型大小)
3. 動態數組(使用指針)
- 堆上分配:使用
new
和delete[]
:int size = 10; int* dynamicArr = new int[size]; // 動態分配數組// 使用數組 for (int i = 0; i < size; i++) {dynamicArr[i] = i; }delete[] dynamicArr; // 釋放內存
四、數組作為函數參數
1. 數組退化問題
- 數組作為參數時會退化為指針,丟失大小信息:
void printArray(int arr[]) { // 等價于 int* arr// sizeof(arr) 返回指針大小(如8字節),非數組大小 }
2. 正確傳遞數組的方法
- 顯式傳遞大小:
void printArray(int arr[], int size) {for (int i = 0; i < size; i++) {cout << arr[i] << " ";} }
- 使用引用:保留數組大小信息:
void printArray(int (&arr)[5]) { // 僅接受長度為5的數組for (int num : arr) {cout << num << " ";} }
- 使用模板:自動推導大小:
template <size_t N> void printArray(int (&arr)[N]) {for (int num : arr) {cout << num << " ";} }
五、C++標準庫替代方案
1. std::array
(C++11起)
- 特點:固定大小數組,封裝在類中,提供更安全的接口。
- 示例:
#include <array>std::array<int, 5> arr = {1, 2, 3, 4, 5};// 安全特性 cout << arr.size(); // 返回5 // arr[10] = 0; // 越界訪問(運行時可能崩潰) arr.at(10) = 0; // 越界訪問(拋出std::out_of_range異常)
2. std::vector
- 特點:動態數組,支持自動擴容。
- 示例:
#include <vector>std::vector<int> vec = {1, 2, 3}; vec.push_back(4); // 動態添加元素 cout << vec.size(); // 返回4
六、常見陷阱與最佳實踐
1. 數組越界訪問
- 問題:訪問超出數組邊界的元素,導致未定義行為。
- 示例:
int arr[3] = {1, 2, 3}; cout << arr[3]; // 越界訪問,可能崩潰或讀取隨機值
2. 內存泄漏(動態數組)
- 問題:忘記釋放
new
分配的內存。 - 解決方案:優先使用
std::vector
或智能指針:#include <memory>// 使用智能指針管理動態數組 std::unique_ptr<int[]> arr(new int[10]);
3. 避免C風格數組
- 建議:優先使用
std::array
或std::vector
替代原始數組,減少手動內存管理:// 推薦寫法 std::array<int, 5> arr; // 固定大小 std::vector<int> vec; // 動態大小
通過合理使用數組和標準庫容器,你能高效處理各種數據存儲需求。建議優先使用std::vector
和std::array
,僅在性能敏感或與C代碼交互時使用原始數組。