在上一篇文章 “C/C++ 指针,数组与退化” 中我们详细解释了如何声明指向数组的指针,在实际应用中,仅仅静态声明一个数组或者其指针是不够用的,还需要返回及动态创建。
返回指向数组指针的函数
基本方法
声明一个返回数组指针的函数的基本形式如下: Type (*function (parameter_list)) [dimension]
。
不过我们理所当然的可以对其进行扩展: Type (*function (parameter_list)) [dimension1][dimension2]...
。
所以,一个基本的返回一维数组的指针的函数如下:
int(*func())[6]//C++ Primer解释为,可以对函数结果进行解引用,因为这个函数的返回值是左值
{
int b[6] = { 1,2,3,4,5,6 };
int(*n)[6] = &b;
return n;
}
** 注意:任何声明都严格匹配维度 **
返回二维数组的指针的函数如下:
int(*func2())[3][2]
{
int b[3][2] = { 1,2,3,4,5,6 };
int(*n)[3][2] = &b;
return n;
}
使用类型别名
由于这种写法并不是很清晰,所以 C/C++ 也允许使用类型别名的方式声明:
typedef int arrT[10];//C,arrT表示一个含有10个元素的整形数组
using arrT = int[10];//C++
arrT* func();
推广开来:
typedef int arrT[3][2];//C,arrT表示一个3x2的二维数组
using arrT = int[3][2];//C++
arrT *func()
{//注意此时*与func()优先结合,而不是与类型别名结合
int b[3][2] = { 1,2,3,4,5,6 };
int(*n)[3][2] = &b;
return n;
}
尾置返回类型
不过使用类型别名其实不是很优雅,首先多了一条语句,其次你需要知道 * 的结合顺序,所以 C++ 11 增加了一种新的方法尾置返回类型:
auto func() -> int(*)[10];
auto func2() -> int(*)[3][2];
根据前文我们知道,声明一个指向数组的指针是这样的:
int a2[3][2] = {1,2,3,4,5,6};
int (*b2)[3][2] = &a2;
尾置返回类型的结构中就直接使用了和声明指针一样的方法,只不过去掉了用户标识符。
decltype 关键字
如果我们在同一个作用域有一个现成的数组,并且确定这个数组是这个函数相关的,那么我们还可以使用 decltype 关键字匹配类型简化声明:
int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};
decltype(odd) *arrPtr(int i)
{
return (i % 2) ? &odd : &even;
}
使用 new 动态创建并返回指针
使用 new 操作符获得一个指向二维数组的指针更是轻车熟路:
int(*n1)[3] = (int(*)[3])new int[3];
int(*n2)[3][2] = (int(*)[3][2])new int[3][2];
参考:C++ Primer 第五版 206 页