概述
根本:数组不能拷贝,所以函数、返回值传递数组变量只能通过数组的指针或者是引用
一、函数返回值问题:指针(注:函数的返回值不能是数组,只能是数组的指针或是引用)
1、函数返回指针(包含动态数组)
声明:int * retArray(int i);
声明:int * retArray(int i)[10];函数返回数组,内部存储为基本数据类型的指针
注:此种定义是错误的,函数返回值为数组是被禁止的,只能通过数组指针或是引用
2、函数返回值是个固定大小的数组指针,数组存储的数据为基本数据类型
声明:int (*retArray(int i))[10] ; //此函数返回值为数组内部为int的10大小数组指针
定义:
int (*retArray(int i))[10]
{
static int a[10] = {1};
return &a;
//对于函数返回值固定[]元素数,需要返回&取地址符
}
3、函数的返回值固定大小的数组指针,数组存储的数据为基本数据类型的指针
声明:int *(* retArray(int i))[10];
定义:
int *(* retArray(int i))[10]
{
int *a[10];
for(int i = 0;i<10;i++)
{
a[10] = &i;
//此处最好不要去局部变量的引用
}
return &a;
}
二、函数返回值问题:引用
1、函数返回引用
声明:int & retArray(int i); 此种声明只能用作返回基本数据类型的变量,不能返回数组
声明 int & retArray(int i)[10]; 函数返回数组,内部存储基本数据类型的引用
注:此种定义是错误的,函数返回值为数组是被禁止的,只能通过数组指针或是引用,且定义引用数组是错误的
2、函数返回值是固定大小的数组引用,数组存储数据为基本数据类型
声明: int (& retArray(int i))[10];
定义:
int (& retArray(int i))[10]
{
int a[10] = {1};
return a;
{
3、函数返回值是固定大小的数组引用,数组内部数据类型为基本数据类型的引用
声明:int &(& retArray(int i))[10];
报错:数组内部存储引用类型数据是不被允许的
三、函数返回值问题:指针、引用混合
1、定义:int *(& retArray(int i))[10];
声明:
int *(& retArray(int i))[10]
{
int *a[10];
for(int i=0;i<10;i++)
{
a[i] = &i;
}
return a;
}
2、定义:int &(* retArray(int i))[10];
报错:不准定义内部为引用类型的数组
四、函数返回值利用类型别名
1、类型别名定义返回值类型
using array = int [10];
typedef int array[10]
//定义array数组
array * retArray(int i);
//返回一个指向含有10个整数的数组指针
array & retArray(int i);
//返回一个含有10个整数数组的别名
2、decltype定义返回值类型
int array[] = {1,2,3,4,5,6,7,8,9,0}
decltype(array) * retArray(int i);
//返回一个指向含有10个整数的数组指针
decltype(array) & retArray(int i);
//返回一个含有10个整数的数组别名
3、使用尾置类型
- 指针:
声明:auto retArray(int i) -> int* (*)[10]; //函数retArray接收整形参数i,返回int*型数组指针
声明:auto retArray(int 0) -> int [10]; //报错,函数不能直接返回数组
- 引用:
声明:auto retArray(int i) -> int (&)[10]; //返回整形数组的引用
声明:auto retArray(int i) -> int &[10] //返回引用数组是不被允许的
- 指针、引用混:
声明:auto retArray(int i) -> int& (*)[10]; //不允许返回引用数组
五、数组作为参数传递。 当声明的数组为指针数组(int (*)[])或者引用数组(int (&)[])的时候需要指定数组的大小
1、指针
- 指针(包含隐含数组,指针的指针类似)声明:int retArray(int *i);
int *i = nullptr;
retArray(i);
- 数组指针
声明:
template <unsigned T,unsigned U>
//非类型参数,代表数值
void retArray(int (*i)[T],int (*j)[U])
调用:
int (*arr)[10];
retArray(arr);
- 数组存储为基本数据类型指针
调用:
int *arr[10];
for (int i;i<10;++i)
{
arr[i] = & i;
//此处不要使用局部变量的引用
}
retArray(arr);
- 数组内部存储基本数据类型指针,形参指向该数组
声明:
template<unsigned T>
int ret(int *(*i)[T])
调用:
int * (*arr)[10] = nullptr;
retArray(arr);
2、引用:
- 基本数据类型引用
调用:
int a =10;
retArray(a);
- 基本数据类型数组的引用
定义:
template <unsigned T,unsigned U>
//非类型参数,代表数值
int retArray(int (&a)[T],int (&b)[U])
调用:
int arr[10] = {1};
retArray(arr);
- 基本数据类型引用数组的引用
报错:定义内部为基本数据类型引用的数组是被禁止的
3、指针、引用混合
- 基本数据类型指针的数组引用
定义:
template<unsigned T>
int ret(int * (&a)[T]);
调用:
int *arr[10];
retArray(arr);
- 基本数据类型引用的数组指针
报错:定义基本数据类型的引用的数组是被禁止的
4、注意
- 数组指针作为函数参数的时候:
指针作为指向内存的变量,当其作为实参变量传给形参时;
内存中也会申请一个指针形参变量的空间来存储指向的变量空间地址,这就涉及到变量到变量拷贝问题;
只不过实参与形参所指向的内存空间一致,可以通过形参来修改实参所指向的空间数值;
所以函数内部修改形参存储的变量值(即变量地址),任由形参指向那个新变量,都不会改变实参的指向的地址值,但修改形参指向空间变量时(前提是实参与形参指向同一个地址)时,实参指向的空间变量值也会被修改。
- 定义指针的指针时:
int **p或者是 int *q[constant];
尤其要注意:
p, q变量的存储空间定义就被初始化,其初始指向的地址为0x0000;指针变量存储的是地址值:0x0000;
q数组内部已经分配了空间,存储全部为0x0000(指向0x0000),且其内部空间必须存储为指向int *的变量,但是数组内部指针指向的空间未指向;
p并没有指向明显空间,但是编译器会让其默认指向0x0000空间(保留空间,无权读写),其指针值存储为0x0000。
注意要为p指向两个空间值:
p = (int **)malloc(sizeof(int));
*p = (int *)malloc(sizeof(int));
- 指针变量地址问题:
int a = 1;
int *pointB = &a;
int *pointC = &a;
//pointB和pointC内部均存储变量a的地址值,即指向的空间相同
cout << pointB;
cout << pointC;
//输出的存储变量地址值相同
//但是存储pointB和pointC指向地址值的空间不是一个空间,只不过他们的指向的空间相同
cout << &pointB;
cout << &pointC;
//输出的存储的指针变量值不同
一句话:指针作为参数传递时是存在副本的,会涉及到指针变量存储的地址值拷贝问题;指针也是基本数据类型,在内存中占用空间
最后
以上就是漂亮路人为你收集整理的理解数组和引用作为参数和返回值传递的全部内容,希望文章能够帮你解决理解数组和引用作为参数和返回值传递所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复