因为数组不能被拷贝,所以函数不能返回数组。函数可以返回数组的指针或引用。
使用类型别名定义一个返回数组的指针或引用的函数:
typedef int arrT[10];//arrT是一个类型别名,它表示的类型是含有10个整数的数组
using arrT=int[10];//arrT的等价声明
arrT* func(int i);//func返回一个指向含有10个整数的数组的指针
arrT 是含有10个整数的数组的别名。因为我们无法返回数组,所以将返回类型定义成数组的指针。
声明一个返回数组指针的函数
要想在声明 func 时不使用类型别名,必须牢记被定义的名字后面数组的维度:
int arr[10];//arr是一个含有10个整数的数组
int* p1[10];//p1是一个含有10个指针的数组
int (*p2)[10]=&arr;//p2是一个指针,它指向含有10个整数的数组
返回数组指针的函数形式:
Type (*function(parameter_list))[dimension]
Type 表示类型,dimension 表示数组大小,(*function(parameter_list)) 两端的括号必须存在。
像定义 p2 时两端必须有括号一样,如果没有这队括号,函数的返回类型将是指针的数组。
func 函数的声明没有使用类型别名:
int (*func(int i))[10];
逐层理解该声明的含义:
func(int i)表示调用 func 函数时需要一个 int 类型的实参。
(*func(int i))意味着我们可以对函数调用的结果执行解引用操作。
(*func(int i))[10]表示解引用 func 的调用将得到一个大小是10的数组。
int (*func(int i))[10]表示数组中的元素是 int 类型。
使用尾置返回类型
尾置返回类型跟在形参列表后面并以一个 -> 符号开发,为了表示函数真正的返回类型跟在形参列表之后,在本应该出现返回类型的地方放置一个 auto :
//func 接受一个 int 类型的实参,返回一个指针,该指针指向含有10个整数的数组
auto func(int i)->int(*)[10];
因为把函数的返回类型放在形参列表之后,可以清楚地看到 func 函数返回的是一个指针,并且该指针指向含有10个整数的数组。
使用 decltype
知道函数返回的指针将指向哪个数组,就可以使用 decltype 关键字声明返回类型。
下面的函数返回一个指针,该指针根据参数 i 的不同指向两个已知的数组中的某一个:
int odd[] = {1,3,5,7,9};
int even[] = { 0,2,4,6,8 };
decltype(odd)* arrPtr(int i)
{
return (i % 2) ? &odd : &even;//返回一个指向数组的指针
}
arrPtr 使用关键字 decltype 表示返回类型是个指针,并且该指针所指的对象和 odd 的类型一致。
因为 odd 是数组,所以 arrPtr 返回一个指向含有5个整数的数组的指针。
注意:decltype 并不负责把数组类型转换成对应的指针,所以 decltype 的结果是个数组,要想表示 arrPtr 返回指针还必须在函数声明时加一个 * 符号。