C++一维数组 #

一、数组概述 #

数组是存储相同类型元素的连续内存空间。

1.1 数组特点 #

  • 元素类型相同
  • 内存连续
  • 大小固定
  • 通过下标访问

1.2 数组声明 #

cpp
// 语法:type name[size];
int arr[5];           // 声明包含5个int的数组
double prices[10];    // 声明包含10个double的数组
char name[20];        // 声明包含20个char的数组

二、数组初始化 #

2.1 完全初始化 #

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

// 使用花括号初始化(C++11)
int arr2[5] {1, 2, 3, 4, 5};

2.2 部分初始化 #

cpp
// 未指定的元素自动初始化为0
int arr[5] = {1, 2};  // {1, 2, 0, 0, 0}

2.3 省略大小 #

cpp
// 编译器自动推断大小
int arr[] = {1, 2, 3, 4, 5};  // 大小为5

2.4 零初始化 #

cpp
int arr[5] = {0};     // {0, 0, 0, 0, 0}
int arr2[5] = {};     // {0, 0, 0, 0, 0}

2.5 常量数组 #

cpp
const int arr[5] = {1, 2, 3, 4, 5};  // 不可修改

三、数组访问 #

3.1 下标访问 #

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

// 读取元素
std::cout << arr[0] << std::endl;  // 10
std::cout << arr[2] << std::endl;  // 30

// 修改元素
arr[0] = 100;
arr[4] = 500;

3.2 下标范围 #

cpp
int arr[5];

// 有效下标:0 到 4
arr[0] = 1;   // 第一个元素
arr[4] = 5;   // 最后一个元素

// 越界访问(未定义行为)
arr[5] = 6;   // 危险!越界
arr[-1] = 0;  // 危险!越界

3.3 遍历数组 #

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

// 使用for循环
for (int i = 0; i < 5; i++) {
    std::cout << arr[i] << " ";
}

// 使用范围for(C++11)
for (int x : arr) {
    std::cout << x << " ";
}

// 使用引用修改
for (int& x : arr) {
    x *= 2;  // 每个元素乘以2
}

四、数组大小 #

4.1 使用sizeof #

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

// 数组总字节数
size_t totalBytes = sizeof(arr);        // 20 (5 * 4)

// 单个元素字节数
size_t elementBytes = sizeof(arr[0]);   // 4

// 元素个数
size_t count = sizeof(arr) / sizeof(arr[0]);  // 5

4.2 使用std::size(C++17) #

cpp
#include <iterator>

int arr[5] = {1, 2, 3, 4, 5};
size_t count = std::size(arr);  // 5

4.3 使用模板函数 #

cpp
template<typename T, size_t N>
constexpr size_t arraySize(T (&)[N]) {
    return N;
}

int arr[5];
size_t count = arraySize(arr);  // 5

五、数组与函数 #

5.1 传递数组给函数 #

cpp
// 数组作为参数时退化为指针
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    printArray(arr, 5);
    return 0;
}

5.2 使用指针参数 #

cpp
void printArray(int* arr, int size) {
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
}

5.3 使用模板保留数组大小 #

cpp
template<size_t N>
void printArray(int (&arr)[N]) {
    for (int i = 0; i < N; i++) {
        std::cout << arr[i] << " ";
    }
}

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    printArray(arr);  // 不需要传递大小
    return 0;
}

5.4 使用std::array(推荐) #

cpp
#include <array>

void printArray(const std::array<int, 5>& arr) {
    for (int x : arr) {
        std::cout << x << " ";
    }
}

六、数组操作 #

6.1 查找元素 #

cpp
int arr[5] = {10, 20, 30, 40, 50};
int target = 30;
int index = -1;

for (int i = 0; i < 5; i++) {
    if (arr[i] == target) {
        index = i;
        break;
    }
}

if (index != -1) {
    std::cout << "找到元素,索引: " << index << std::endl;
}

6.2 求和与平均值 #

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

for (int x : arr) {
    sum += x;
}

double average = static_cast<double>(sum) / 5;
std::cout << "总和: " << sum << std::endl;
std::cout << "平均值: " << average << std::endl;

6.3 找最大最小值 #

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

int maxVal = arr[0];
int minVal = arr[0];

for (int i = 1; i < 5; i++) {
    if (arr[i] > maxVal) maxVal = arr[i];
    if (arr[i] < minVal) minVal = arr[i];
}

std::cout << "最大值: " << maxVal << std::endl;
std::cout << "最小值: " << minVal << std::endl;

6.4 数组复制 #

cpp
int source[5] = {1, 2, 3, 4, 5};
int dest[5];

// 手动复制
for (int i = 0; i < 5; i++) {
    dest[i] = source[i];
}

// 使用std::copy
#include <algorithm>
std::copy(std::begin(source), std::end(source), std::begin(dest));

// 使用memcpy
#include <cstring>
std::memcpy(dest, source, sizeof(source));

6.5 数组排序 #

cpp
#include <algorithm>

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

// 升序排序
std::sort(std::begin(arr), std::end(arr));
// arr = {10, 20, 30, 40, 50}

// 降序排序
std::sort(std::begin(arr), std::end(arr), std::greater<int>());
// arr = {50, 40, 30, 20, 10}

七、变长数组 #

7.1 使用变量定义大小(非标准) #

cpp
int n = 5;
int arr[n];  // 非标准C++,但某些编译器支持

// 推荐:使用常量
const int N = 5;
int arr2[N];  // 标准C++

7.2 使用动态数组 #

cpp
int n = 5;
int* arr = new int[n];  // 动态分配

// 使用
for (int i = 0; i < n; i++) {
    arr[i] = i + 1;
}

// 释放
delete[] arr;

7.3 使用std::vector(推荐) #

cpp
#include <vector>

int n = 5;
std::vector<int> arr(n);  // 大小可变

for (int i = 0; i < n; i++) {
    arr[i] = i + 1;
}

八、数组常见错误 #

8.1 越界访问 #

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

// 危险:越界访问
std::cout << arr[5] << std::endl;   // 未定义行为
std::cout << arr[-1] << std::endl;  // 未定义行为

// 安全访问
int index = 5;
if (index >= 0 && index < 5) {
    std::cout << arr[index] << std::endl;
}

8.2 数组退化 #

cpp
void func(int arr[]) {
    // sizeof(arr) 是指针大小,不是数组大小
    std::cout << sizeof(arr) << std::endl;  // 8(64位系统)
}

int main() {
    int arr[5];
    std::cout << sizeof(arr) << std::endl;  // 20
    func(arr);  // 数组退化为指针
}

8.3 未初始化 #

cpp
int arr[5];  // 未初始化,元素值不确定

// 推荐:始终初始化
int arr2[5] = {};  // 全部初始化为0

九、std::array(C++11) #

9.1 基本使用 #

cpp
#include <array>

std::array<int, 5> arr = {1, 2, 3, 4, 5};

// 访问元素
std::cout << arr[0] << std::endl;
std::cout << arr.at(0) << std::endl;  // 带边界检查

// 获取大小
std::cout << arr.size() << std::endl;

// 遍历
for (int x : arr) {
    std::cout << x << " ";
}

9.2 std::array vs 原生数组 #

特性 原生数组 std::array
大小获取 sizeof计算 size()方法
边界检查 at()方法
赋值 不能直接赋值 可以直接赋值
作为参数 退化为指针 保留大小

十、总结 #

数组要点 #

操作 语法
声明 type name[size]
初始化 {v1, v2, ...}
访问 arr[index]
大小 sizeof(arr)/sizeof(arr[0])
遍历 for (int x : arr)

最佳实践 #

  1. 始终初始化数组
  2. 避免越界访问
  3. 使用std::array代替原生数组
  4. 使用std::vector处理动态大小

下一步,让我们学习多维数组!

最后更新:2026-03-26