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 <h3>多个数组一起改,参数怎么列</h3>
<p>多个数组要同时修改,就多个引用参数并列,但注意:每个数组类型必须明确,不能混用不同长度或类型。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架"><img
src="https://img.php.cn/upload/skill/000/000/081/178988956499722.jpg" alt="C++ 算法竞赛自动化测试数据生成与校验框架" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="overflowclass">C++ 算法竞赛自动化测试数据生成与校验框架</a>
<p class="overflowclass">根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。</p>
</div>
<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>同类型同长度:直接写多个相同引用,如 <code>void f(int (&a)[3], int (&b)[3])</code>
</li>
<li>不同长度:必须用模板分别推导:<code>template<size_t n size_t m> void f(int (&a)[N], int (&b)[M])</size_t></code>
</li>
<li>混用 <code>std::array</code> 和 <code>std::vector</code>:可以,但得写清楚类型,比如 <code>void f(std::array<float>& a, std::vector<double>& v)</double></float></code>
</li>
<li>千万别写 <code>void f(int* a, int* b)</code> 并指望靠注释“告诉调用方我改了它们”——没语法保障,容易误用</li>
</ul>
<h3>为什么不用返回值打包多个数组</h3>
<p>返回多个数组不是不行,但代价高、意图模糊。常见错误是试图 return 多个局部数组,结果返回悬垂指针。</p>
<ul>
<li>
<code>std::tuple<:array>, std::array<float>></float></:array></code> 可行,但调用方得用 <code>std::get(t)</code> 拆包,写起来啰嗦,且每次调用都触发拷贝</li>
<li>
<code>std::pair</code> 或结构体只适合固定、少量返回项;一旦加到三个以上,命名和维护成本陡增</li>
<li>真正需要“返回新数组”时,才该用返回值;若目标是“让输入数组被修改”,引用参数语义更清晰、零开销</li>
</ul>
<h3>容易踩的坑:const、生命周期和 vector 的 capacity</h3>
<p>看似简单,实际几个点一错就静默失败:</p>
<ul>
<li>参数加了 <code>const &</code> 就没法修改——检查函数声明有没有多余 <code>const</code>
</li>
<li>传 <code>std::vector</code> 引用时,如果函数内部调用了 <code>v.push_back()</code> 导致重分配,原引用仍有效,但要注意迭代器失效;而 <code>std::array</code> 容量固定,不存在扩容问题</li>
<li>用 <code>std::vector</code> 但只改元素值(不增删),<code>capacity()</code> 不变,没问题;但若误以为 <code>size()</code> 会变,其实是不会的——得显式调用 <code>resize()</code>
</li>
<li>模板推导失败常见于传入指针或 <code>new</code> 出来的数组:这些无法匹配引用数组形参,编译直接报错,得回头检查实参是不是字面量数组或栈上定义的</li>
</ul>
<p>最常被忽略的是:C 风格数组引用形参对齐要求严格,<code>alignas(16) int a[4]</code> 和普通 <code>int b[4]</code> 类型不兼容,模板实例化会失败。这种细节只有在混合 SIMD 操作时才会暴露。</p></size_t>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










