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

C++函数内数组修改生效但普通传值变量不生效的原因

C++数组传参修改原内容的原因

问题复现代码

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

void func(int arr[5], int n1, int n2)
{   
    cout << "INSIDE func()" << endl;
    arr[0]++, arr[3]++;
    for(int i = 0; i < 5; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
    n1++, n2++;
    cout << n1 << ' ' << n2 << endl;
}

int main()
{
    int a = 3, b = 4;
    int arr[5] = {0,0,0,0,0};
    
    func(arr,a,b);
    cout << "INSIDE main()" << endl;
    for(int i = 0; i < 5; i++)
    {
        cout << arr[i] << ' ';
    }
    cout << endl;
    cout << a << ' ' << b << endl;

    return(0);
}

运行现象

代码运行输出如下:

INSIDE func()
1 0 0 1 0
4 5
INSIDE main()
1 0 0 1 0
3 4

可以观察到两个明显差异:

  • 函数内对arr数组元素的修改,回到main函数后仍然保留
  • 函数内对普通形参n1、n2的自增修改,回到main后完全不影响原变量a、b的值

已知要让函数内对普通变量的修改作用到外层实参,可以通过引用传参实现,示例写法如下:

void func(int arr[5], int &n1, int &n2)
{
   /* 内部直接操作n1、n2等价于操作外层原变量 */
}

核心原因

这个差异本质是C++的数组退化规则和默认值传递规则共同导致的:

  1. 普通变量默认是值传递
    调用函数传普通变量时,编译器会为形参开辟独立的内存空间,把实参的值拷贝一份存进去。函数内部对形参的所有修改,都是在操作这份独立的拷贝,和外层的原变量没有关联,离开函数作用域后形参被销毁,修改自然不会保留。如果要修改原变量,就需要给形参加&用引用传递,让形参成为原变量的别名,操作形参就是直接操作原变量的内存。
  2. 数组传参会自动退化为首元素指针
    你写的形参int arr[5]只是C的语法糖,根据C标准,数组类型作为函数形参时会被自动调整为指向数组首元素的指针,也就是说int arr[5]、int arr[]、int* arr这三种形参写法在编译器看来完全等价,都会被处理成int* arr类型的指针形参。
    调用func(arr,a,b)时,传给形参arr的不是整个数组的拷贝,而是原数组首元素的内存地址。函数内写arr[0]++本质是指针偏移+解引用操作,等价于*(arr + 0) += 1,直接读写的是原数组所在的内存地址上的值,根本没有操作拷贝副本,修改当然会直接反映到原数组上。

注意点

  • 不要误以为数组传参是特殊的“引用传递”:本质上数组形参还是值传递,只不过传的“值”是指针(内存地址),拷贝的是指针本身,不是整个数组。你如果在函数内给arr指针本身重新赋值(比如写arr = nullptr),外层的原数组不会受任何影响,因为你改的是指针的拷贝;但你通过指针解引用改指向的内存内容,改的就是原数组的数据。
  • 如果真的要传递数组的引用,需要写成专门的引用语法:void func(int (&arr)[5], int n1, int n2),这种写法下数组不会发生指针退化,你在函数内取sizeof(arr)能得到整个数组的真实长度(20字节,按int占4字节算),而不是指针的长度(8字节/64位环境、4字节/32位环境)。
  • 普通变量如果传指针也能达到和数组传参一样的效果,比如形参写成void func(int arr[5], int* n1, int* n2),调用时传func(arr, &a, &b),函数内写(*n1)++、(*n2)++也能修改外层a、b的值,本质和数组传参的逻辑完全一致:传地址过去,解引用改原内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:21:29