C++中的数组

发布于:2025-06-09 ⋅ 阅读:(19) ⋅ 点赞:(0)

在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. 动态数组(使用指针)
  • 堆上分配:使用newdelete[]
    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::arraystd::vector替代原始数组,减少手动内存管理:
    // 推荐写法
    std::array<int, 5> arr;  // 固定大小
    std::vector<int> vec;    // 动态大小
    

通过合理使用数组和标准库容器,你能高效处理各种数据存储需求。建议优先使用std::vectorstd::array,仅在性能敏感或与C代码交互时使用原始数组。


网站公告

今日签到

点亮在社区的每一天
去签到