如何解决将指针返回二维数组[C ++]
我不知道为什么,但是它不返回我在函数中声明的二维数组。
char** canvas() {
char canvas[18][8];
fill(canvas[0],canvas[0] + 18 * 8,'O');
return canvas;
}
解决方法
canvas
是一个局部变量,当函数超出作用域时,其生存期将终止,然后通过指针访问此变量将调用未定义的行为。
该函数的返回类型也与您要返回的对象不兼容。
如果必须使用 C样式数组(从您的评论中推断),则可以执行以下操作:
char (*canvas())[8] //pointer to array return type
{
char (*canvas)[8] = new char[18][8]; //C++ manual allocation
//std::fill(canvas[0],canvas[0] + 18 * 8,'O'); //works
std::fill_n(canvas[0],18 * 8,'O'); //better,as suggested by Ted Lyngmo
return canvas;
}
然后您可以这样称呼它:
int main()
{
char(*canv)[8] = canvas(); //assign it
for (int i = 0; i < 18; i++) //use it like a 2D array
{
for (int j = 0; j < 8; j++)
{
std::cout << canv[i][j];
}
std::cout << std::endl;
}
delete[] canv; //delete object after it's used
}
在使用C ++时,我建议使用类似std::vector
的STL容器,即向量std::vector<std::vector<char>>
的向量,也可以使用std::array
,因为在编译时已知尺寸,即std::array<std::array<char,8>,18>
。
对于C ++ std::array
实现:
std::array<std::array<char,18> canvas()
{
std::array<std::array<char,18> canvas;
std::fill_n(canvas.begin()->begin(),'O');
return canvas;
}
int main()
{
std::array<std::array<char,18> canv = canvas();
//...
}
对于std::vector
实现:
std::vector<std::vector<char>> canvas()
{
std::vector<std::vector<char>> canvas{18,std::vector<char>(8,'0')};
return canvas;
}
int main()
{
std::vector<std::vector<char>> canv = canvas();
//...
}
在两种情况下,您都可以像第一个示例一样使用 C风格 for
循环,但是也可以使用基于范围的for wich更好,因为这样可以避免达到超出数组范围,因此避免了未定义的行为。
for (auto& a : canv)
{
for (auto& ch : a)
{
std::cout << ch;
}
std::cout << std::endl;
}
所有情况下的输出:
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
OOOOOOOO
,
一个常见的误解是,由于char[n]
可转换为char*
也必须能够将char[n][m]
转换为char**
,但这不是真的。
问题是char[n]
和char*
的元素相同。每个元素都是一个char
,因此可以进行转换。
但是对于char[n][m]
,每个元素都是char[m]
,对于char**
,每个元素都是char*
。这些不一样,并且转换无效。
简单的解决方案是使用向量而不是数组。
vector<vector<char>> canvas(){
vector<vector<char>> canvas(18,vector<char>(8));
fill(canvas[0],'O');
return canvas;
}
,
这可能是一种奇怪的语法:
char (*canvas())[8] //pointer to array return type
使用类型别名可以提高可读性:
using canvas_ptr = char (*)[8];
因此您可以通过以下方式编写c样式的解决方案:
canvas_ptr getCanvas()
{
canvas_ptr canvas = new char[18][8]; //C++ allocation
std::cout << "size:" << std::size(canvas) << '\n';
std::fill_n(canvas[0],'O'); //as suggested by Ted Lyngmo
return canvas;
}
int main()
{
canvas_ptr c = getCanvas();
for (int i = 0; i < 18; i++) //use it like a 2D array
{
for (int j = 0; j < 8; j++)
{
std::cout << c[i][j];
}
std::cout << std::endl;
}
delete[] c; //delete object after it's used
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。