1. 数组是什么?

想象一下你有一排整齐的邮箱📬,每个邮箱都有一个编号(索引)和一个存放内容的空间。数组就是这样一种数据结构:

  • 存储相同类型的多个数据元素
  • 元素在内存中连续排列
  • 通过索引(位置编号)访问元素
小贴士: 数组索引从0开始!第一个元素索引是0,第二个是1,以此类推。

2. 数组的声明和初始化

创建数组就像在仓库里预定一排储物柜:

// 声明一个包含5个整数的数组
int scores[5]; // 未初始化,值是随机的

// 声明并初始化数组
int primes[5] = {2, 3, 5, 7, 11};

// 自动计算数组大小
double temperatures[] = {25.5, 26.0, 24.8, 23.7}; // 大小为4

// C++11初始化方式
int zeros[10]{}; // 所有元素初始化为0
注意: 数组大小一旦确定就不能改变!如果需要动态大小,考虑使用vector。

3. 访问数组元素

就像通过门牌号找到对应的房子一样,通过索引访问数组元素:

int numbers[5] = {10, 20, 30, 40, 50};

// 获取第一个元素(索引0)
int first = numbers[0]; // first = 10

// 修改第三个元素(索引2)
numbers[2] = 100; // 数组变为 {10, 20, 100, 40, 50}

// 使用变量作为索引
int index = 4;
int last = numbers[index]; // last = 50
重要警告: 不要访问超出数组范围的元素!这会导致程序崩溃或产生不可预测的结果。

4. 数组的遍历

遍历数组就是挨个访问数组中的每个元素,就像检查一排储物柜:

使用for循环

int arr[5] = {1, 2, 3, 4, 5};

// 传统for循环遍历
for (int i = 0; i < 5; i++) {
    cout << arr[i] << " "; // 输出每个元素
}
// 输出: 1 2 3 4 5

使用范围for循环(C++11)

for (int num : arr) {
    cout << num << " ";
}
// 输出: 1 2 3 4 5

5. 多维数组

多维数组就像是公寓楼,有楼层和房间号:

// 声明一个3×3的二维数组(矩阵)
int matrix[3][3] = {
    {1, 2, 3}, // 第0行
    {4, 5, 6}, // 第1行
    {7, 8, 9} // 第2行
};

// 访问元素 – 第1行第2列
int element = matrix[1][2]; // element = 6

// 嵌套循环遍历二维数组
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        cout << matrix[i][j] << " ";
    }
    cout << endl;
}
/* 输出:
1 2 3
4 5 6
7 8 9
*/

6. 数组与指针的关系

数组名其实是一个指向数组第一个元素的指针:

int arr[5] = {10, 20, 30, 40, 50};

// arr 等价于 &arr[0]
int* ptr = arr; // 指向数组的第一个元素

// 通过指针访问元素
cout << *ptr; // 输出第一个元素: 10
cout << *(ptr+1); // 输出第二个元素: 20
cout << ptr[2]; // 输出第三个元素: 30

// 指针运算遍历数组
for (int* p = arr; p < arr+5; p++) {
    cout << *p << " ";
}
// 输出: 10 20 30 40 50
理解: 数组名是一个常量指针,不能改变它的指向。但可以用另一个指针变量来遍历数组。

7. 数组作为函数参数

当把数组传递给函数时,实际传递的是数组第一个元素的地址:

// 函数声明 – 数组参数
void printArray(int arr[], int size);

int main() {
    int myArray[5] = {1, 2, 3, 4, 5};
    printArray(myArray, 5); // 传递数组和大小
}

// 函数定义
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        cout << arr[i] << " ";
    }
}
注意: 函数内无法直接获取数组大小(sizeof操作符返回的是指针大小),所以通常需要传递数组大小。

8. C++11新特性:std::array

传统C数组有些缺点,C++11引入了更安全的std::array:

特性 传统数组 std::array
大小固定
知道自身大小 是(size()方法)
边界检查 有(at()方法)
可作为返回值
支持迭代器
// 使用std::array
#include <array>

int main() {
    std::array<int, 5> myArray = {1, 2, 3, 4, 5};

    // 访问元素
    cout << myArray[0]; // 1
    cout << myArray.at(1); // 2(带边界检查)

    // 获取大小
    cout << myArray.size(); // 5

    // 范围for循环
    for (int num : myArray) {
        cout << num << " ";
    }
}