You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

数组传递默认退化为指针,为何要使用int(&)[]数组引用传递?

数组传参:为什么要用数组引用 int (&arr)[3]?

请看示例:

#include <iostream>
using namespace std;

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

int Test() {
    int arr[3] = { 0, 0, 0 };

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    Change(arr);

    for (int i = 0; i < 3; i++) {
        cout << arr[i] << endl;
    }

    return 0;
}

由于数组在传递时默认会退化为指向其首元素的指针而非被复制,因此在函数中修改数组元素的值,会直接改变调用者处对应数组元素的值,上述代码输出如下:

0
0
0
1
1
1

既然如此,为什么还需要使用如下方式传递数组呢?

void Change(int (&arr)[3])

我知道括号是为了将参数声明为数组引用而非引用数组,但这么做能带来什么好处?


核心优势:完整保留数组的类型信息

用int arr[3]传参时,编译器会自动将其解析为int* arr,数组的长度信息完全丢失;而数组引用int (&arr)[3]则会完整保留数组的长度和数组类型,带来以下关键好处:

1. 编译期检查,避免越界风险

如果函数内写了超出数组长度的循环(比如把i < 3写成i < 5),数组引用形式会触发编译器报错,提前拦截越界问题;而指针形式下,编译器不知道数组真实长度,只会在运行时可能出现崩溃,很难提前排查。

2. 直接获取数组真实长度

在函数内部,你可以通过sizeof(arr)/sizeof(arr[0])或C++11的std::size(arr)直接拿到数组的实际长度,不需要额外传递长度参数。比如:

void Change(int (&arr)[3]) {
    // 编译期确定长度为3
    cout << "数组长度:" << std::size(arr) << endl;
    for (int i = 0; i < std::size(arr); i++) {
        arr[i] = 1;
    }
}

如果是指针形式,sizeof(arr)得到的是指针本身的大小(比如64位系统下是8字节),根本无法获取数组长度,必须手动传参,容易出现参数不匹配的错误。

3. 强制参数类型匹配,阻止错误调用

数组引用的参数是固定长度的数组类型,如果试图传递长度不符的数组(比如int arr[5]),编译器会直接报错,避免把错误长度的数组传入函数;而指针形式下,任何int*类型(包括其他长度的数组、甚至独立指针)都能传入,极易引发逻辑错误。

4. 结合模板实现通用数组处理

搭配模板可以写出适配任意长度数组的通用函数,同时保留类型安全:

template <size_t N>
void Change(int (&arr)[N]) {
    for (int i = 0; i < N; i++) {
        arr[i] = 1;
    }
}

不管是int arr[3]还是int arr[5]都能调用该函数,编译器会自动推导数组长度N,兼顾灵活性与安全性。

内容的提问来源于stack exchange,提问作者Francesco Derme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 12:24:52