c++数组传递参数与返回

Posted bitcarmanlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++数组传递参数与返回相关的知识,希望对你有一定的参考价值。

1.数组传递参数以后不能计算长度

如果我们以数组作为参数传递,是无法直接计算得到数组长度的。

为了验证上述结论,我们参考以下代码:

#include<iostream>
using namespace std;

void t1(int nums[]) 
    cout<<"nums length is: "<<sizeof(nums)<<endl;


void fun1() 
    int nums[] = 1, 2, 3, 4, 5;
    t1(nums);


int main(int argc, char const *argv[])

    fun1();
    return 0;

代码输出

test_code.cc:5:37: warning: sizeof on array function parameter will return size of 'int *' instead of 'int []' [-Wsizeof-array-argument]
    cout<<"nums length is: "<<sizeof(nums)<<endl;
                                    ^
test_code.cc:4:13: note: declared here
void t1(int nums[]) 
            ^
1 warning generated.
nums length is: 8

虽然代码没有报错能编译运行,但是已经很明确提醒我们了:
sizeof作用在参数为整形数组形式的时候,返回的int *指针的大小,而不是int []数组的真实大小。

因为c++在传递数组的时候,虽然传递的是数组首元素的地址。但是当参数传入到函数内部的时候,就变成了一个普通指针,而不在是数组的首元素地址。因此如果在别的其他函数中试图直接得到该数组的长度是不可以的。

如果我们需要数组的长度,可以先计算出来,再传递到函数内。

#include<iostream>
using namespace std;

void t1(int nums[], int length) 
    cout<<"nums length is: "<<length<<endl;
    cout<<"in t1, nums is: "<<nums<<endl;


void fun1() 
    int nums[] = 1, 2, 3, 4, 5;
    int length = sizeof(nums) / sizeof(nums[0]);
    cout<<"in fun1, nums is: "<<nums<<endl;
    t1(nums, length);


int main(int argc, char const *argv[])

    fun1();
    return 0;

in fun1, nums is: 0x7ffeea1fa2a0
nums length is: 5
in t1, nums is: 0x7ffeea1fa2a0

可以看出,虽然在t1传递的是nums的首元素地址,但是在t1中已经退化成一个普通指针,并不是数组本身。

2.数组引用

如果我们不传递数组指针,而是传递引用,可以解决上述问题

void t2(int (&a)[3])  
    cout<<sizeof(a)<<endl;


int main(int argc, char const *argv[])

    int a[] = 1, 2, 3;
    t2(a);
    return 0;

需要注意的是,传递数组引用的时候是可以知道数组大小的,但是需要指定数组大小。如果传入的数组大小,与指定大小不一致,程序无法编译通过。

void t2(int (&a)[3])  
    cout<<sizeof(a)<<endl;


int main(int argc, char const *argv[])

    int a[] = 1, 2, 3, 4;
    t2(a);
    return 0;

test_code.cc:23:5: error: no matching function for call to 't2'
    t2(a);
    ^~
test_code.cc:16:6: note: candidate function not viable: no known conversion from 'int [4]' to 'int (&)[3]' for 1st argument
void t2(int (&a)[3])  
     ^
1 error generated.

上面的方式可以直接获取数组长度,那与指针相比,有啥劣势不?
相信聪明的读者一眼能看出来,引用传递的时候,有个要命的地方,编译器需要检查形参与实参的大小,且必须保持一致。如果不一致就无法编译通过。这样就导致程序的扩展性较差,而指针的灵活度较高。

3.数组作为函数返回值

首先直接说结论:
c++中不能直接返回一个数组,但是可以让函数返回指针来实现!

int[] t3() 

上述方法,IDE会直接报错告诉你

function cannot return array type 'int []'

改变一下返回方式,返回一个int*类型,就可以实现返回数组等效的目的。

int* t3(int (&a)[5]) 
    int *p = a;
    for(int i=0; i<5; i++) 
        a[i] *= 2;
    
    return p;


int main(int argc, char const *argv[])

    int a[] = 1, 2, 3, 4, 5;
    int *p = t3(a);
    for(int i=0; i<5; i++) 
        cout<<a[i]<<endl;
    
    return 0;

2
4
6
8
10

4.不要返回函数内部创建数组

函数体内部创建的变量都为局部变量。函数运行结束以后,局部变量都会被销毁。如果返回该数组,返回的其实是一个tmp指针,该指针虽然是我们需要的,但是当函数结束以后,也就是遇到return语句,该tmp指针指向的内容就已经发生了变化,不再是我们预期的内容。

int* t4() 
    int nums[] = 1, 2, 3;
    return nums;


int main(int argc, char const *argv[])

    int* nums = t4();
    while(nums) 
        cout<<*nums++<<endl;
    
    return 0;

上面代码运行以后

......
1667594341
1650553973
1717527916
1030057065
959543344
808464688
875573296
863514668
909718576
912471602
1819894784
1768316772
809330028
809054584
808464433
741617712
1717991472
1717986918
808464486
825700656
57
0

显然此时内存里面存储的内容,已经不是我们预期的。

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于c++数组传递参数与返回的主要内容,如果未能解决你的问题,请参考以下文章

C++ 指针与数组

C#和C++传递结构体

C++中数组作为形参进行传递(转)

使用 Python、C++ 和 pybind11 返回和传递原始 POD 指针(数组)

java数组作为参数传入函数怎么让他不变化

将结构数组从 C# 传递到 C++