C++中修改数组首选引用参数:固定大小用模板推导数组引用(如int (&arr)[N]),或std::array;变长用std::vector引用;多数组同改需分别声明引用参数,避免指针退化与悬垂问题。

用引用参数接收数组并修改
直接传数组名在C++里会退化成指针,丢失长度信息,且无法通过参数“返回”修改——除非用引用。最稳妥的方式是把数组类型(含大小)作为模板参数推导,函数体内直接修改原数组:
-
std::array是首选:类型安全、自带size()、可拷贝,且能用引用传参避免复制 - 原始 C 风格数组(如
int arr[5])必须用引用声明:void func(int (&arr)[5]),否则传进去就只剩指针 - 如果数组长度不固定,别硬写死尺寸,改用
std::vector+ 引用,比如void func(std::vector<int>& v)</int>
示例:
template<size_t N>
void double_and_shift(int (&arr)[N]) {
for (size_t i = 0; i < N; ++i) {
arr[i] *= 2;
}
// 原地修改,调用方数组内容已变
}多个数组一起改,参数怎么列
多个数组要同时修改,就多个引用参数并列,但注意:每个数组类型必须明确,不能混用不同长度或类型。
- 同类型同长度:直接写多个相同引用,如
void f(int (&a)[3], int (&b)[3]) - 不同长度:必须用模板分别推导:
template<size_t N, size_t M> void f(int (&a)[N], int (&b)[M]) - 混用
std::array和std::vector:可以,但得写清楚类型,比如void f(std::array<float, 4>& a, std::vector<double>& v) - 千万别写
void f(int* a, int* b)并指望靠注释“告诉调用方我改了它们”——没语法保障,容易误用
为什么不用返回值打包多个数组
返回多个数组不是不行,但代价高、意图模糊。常见错误是试图 return 多个局部数组,结果返回悬垂指针。
立即学习“C++免费学习笔记(深入)”;
-
std::tuple<std::array<int,3>, std::array<float,5>>可行,但调用方得用std::get<0>(t)拆包,写起来啰嗦,且每次调用都触发拷贝 -
std::pair或结构体只适合固定、少量返回项;一旦加到三个以上,命名和维护成本陡增 - 真正需要“返回新数组”时,才该用返回值;若目标是“让输入数组被修改”,引用参数语义更清晰、零开销
容易踩的坑:const、生命周期和 vector 的 capacity
看似简单,实际几个点一错就静默失败:
- 参数加了
const &就没法修改——检查函数声明有没有多余const - 传
std::vector引用时,如果函数内部调用了v.push_back()导致重分配,原引用仍有效,但要注意迭代器失效;而std::array容量固定,不存在扩容问题 - 用
std::vector但只改元素值(不增删),capacity()不变,没问题;但若误以为size()会变,其实是不会的——得显式调用resize() - 模板推导失败常见于传入指针或
new出来的数组:这些无法匹配引用数组形参,编译直接报错,得回头检查实参是不是字面量数组或栈上定义的
最常被忽略的是:C 风格数组引用形参对齐要求严格,alignas(16) int a[4] 和普通 int b[4] 类型不兼容,模板实例化会失败。这种细节只有在混合 SIMD 操作时才会暴露。


















