int arr[]在函数参数中等价于int*,因数组名会退化为指针并丢失长度;推荐用std::vector替代,或模板推导栈数组长度,堆数组必须显式传长度。

为什么 int arr[] 在函数参数里等价于 int*
这是 C++(继承自 C)的语法设计:数组名作为函数参数时,编译器自动将其“退化”为指向首元素的指针,丢失长度信息。哪怕你写 void foo(int arr[10]),sizeof(arr) 仍是指针大小(通常是 8),不是 40。
用 std::vector 替代裸数组是最直接的解法
std::vector 自带大小、支持拷贝/移动、可变长,且传递时不会退化:
void process(const std::vector<int>& v) {
std::cout <ul>
<li>传参用 <code>const std::vector<t>&</t></code> 避免拷贝开销</li>
<li>若需修改原数组,去掉 <code>const</code>;若需所有权转移,用 <code>std::vector<t>&&</t></code>
</li>
<li>调用方无需改逻辑: <code>process({1,2,3});</code> 或 <code>process(my_vec);</code>
</li>
</ul>
<h3>必须用裸数组?用模板推导长度</h3>
<p>如果接口受限(比如对接 C API 或性能敏感场景),可用模板让编译器在编译期捕获数组长度:</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>
<pre class="brush:php;toolbar:false;">template <size_t n>
void process(int (&arr)[N]) {
std::cout <ul>
<li>只能接受真正的栈数组(如 <code>int a[5]; process(a);</code>),不能接受 <code>new int[5]</code> 或指针</li>
<li>无法用于动态分配的堆数组——因为堆数组长度在运行时才确定,模板无法推导</li>
<li>函数重载时注意:该签名和 <code>void process(int*)</code> 是不同函数,不会冲突</li>
</ul>
<h3>传堆分配数组时,必须显式传长度</h3>
<p>对 <code>int* p = new int[n]</code> 这类情况,C++ 没有银弹。你必须手动把长度一起传过去:</p>
<pre class="brush:php;toolbar:false;">void process(int* arr, size_t len) {
for (size_t i = 0; i
- 别依赖
nullptr结尾——这不是字符串,没有约定终止符 - 避免只传指针再用
strlen-style 逻辑探测长度,会越界 - 如果用智能指针管理内存,建议搭配
std::unique_ptr<int></int>和额外的size_t参数
最易被忽略的是:模板方案看似完美,但一旦数组来自 malloc、new[] 或函数返回值(如 std::vector::data()),它就完全失效——此时你面对的已经是裸指针,编译器再也看不到原始维度。这时候硬要绕开长度参数,只会埋下越界访问的隐患。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










