自定义函数中传入三维数组
我想完成的是将一个三维数组取出其中的一部分(我把三维数组想成一个三维的坐标系,x,y,z三个方向)
但是定义函数的时候如何写?
int* list_slices(int* listA, int init_x, int end_x, int init_y, int end_y)
listA是原数组,后面的参数分别为x,y方向的起始和终止坐标,z方向不用管
但是函数中有一个赋值语句
listB = listA;
编译的时候会报错
然后我就把参数listA的传入类型改成 int listA[][],
x,y方向每次调用的值不同,所以不能固定的写出来,z方向固定为3
但这样也会报错,错误原因是参数写的时候除了第一维不用写,剩下的需要写出固定值
我现在就比较蒙,想不出什么办法解决,求各位大神帮忙
以下为源代码
int* list_slices(int* listA, int init_x, int end_x, int init_y, int end_y)
{
int len_x = end_x - init_x + 1;
int len_y = end_y - init_y + 1;
int listB;
for(int i=init_x-1; i<end_x; i++)
{
for(int j=init_y-1; j<end_y; j++)
{
for(int k=0; k<3; k++)
{
listB = listA;
}
}
}
return listB;
} 本帖最后由 impossible 于 2016-8-21 10:14 编辑
shuofxz 发表于 2016-8-20 16:11
对的,这也是问题之一,但是每次调用函数的时候,x y都是不固定的,所以不能知道数组第一维和第二维的长 ...
帮你改了一下代码
#include <iostream>
#include <cstring>
template<typename T>
void* list_slices(void* listA,int y,int z,int init_x, int end_x, int init_y, int end_y)
{
unsigned size=(end_x-init_x+1)*(end_y-init_y+1)*z;
void *listB=reinterpret_cast<void*>(new T);
memcpy(listB,reinterpret_cast<T(*)>(listA)+init_x,size*sizeof(T));
return listB;
}
int main()
{
int a={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26};
int (*b)=reinterpret_cast<int(*)>(list_slices<int>( a,3,3, 1,2, 0,2));
for(int x=0;x<2;x++)
for(int y=0;y<3;y++)
for(int z=0;z<3;z++)
std::cout<<b<<std::endl;
delete []b;
return 0;
}
y,z分别对应原数组那后两个框,返回值要用强制转换为数组指针,T为数组类型,检查要取出的小部分有没有超出被取出数组的长度就不写了.{:9_239:} listB[-2][-2]=listA,有问题 edc41113359 发表于 2016-8-20 02:40
listB[-2][-2]=listA,有问题
额。。重点不在这里吧 =。=
而且for循环的初始值为init_x-1
for(int i=init_x-1; i<end_x; i++)
所以并不会出现为负数的情况 @小甲鱼 小甲鱼老师求助{:10_302:} 本帖最后由 impossible 于 2016-8-20 14:00 编辑
int listB;数组不支持这样吧 impossible 发表于 2016-8-20 11:29
int listB;数组不支持这样吧
对的,这也是问题之一,但是每次调用函数的时候,x y都是不固定的,所以不能知道数组第一维和第二维的长度
有什么解决办法么? 看看 impossible 发表于 2016-8-20 19:07
帮你改了一下代码
y,z分别对应原数组那后两个框,返回值要用强制转换为数组指针,T为数组类型,检查 ...
我C++学的不是很好,看代码有一些疑问
1、template<typename T>这个是什么意思?我查了一下是说定义一个无类型的T 那为什么T又可以表示数组类型
2、void*是怎么回事呀?
3、memcpy(listB,reinterpret_cast<int(*)>(listA)+init_x,size*sizeof(T)); 这个我查资料看了半天也没搞明白是怎么运算的。。。
4、int (*b) 为什么这样定义?b不应该是一个三维数组么,这样看着是二维数组呀,还有为什么要用指针,在外面还有个括号?
可能问了一些比较愚蠢的问题,不要嫌弃=。= 本帖最后由 impossible 于 2016-8-21 10:56 编辑
shuofxz 发表于 2016-8-21 08:30
我C++学的不是很好,看代码有一些疑问
1、template这个是什么意思?我查了一下是说定义一个无类型 ...
1.template<typename T>是一个模板,list_slices<int>( a,3,3, 1,2, 0,2)<这个中间的int>会替换掉函数定义里面所有的T,如果你填入char就是char替换掉T。应为我写的提取三维数组是按字节复制的,每个类型大小又不一样,所以就必须要知道要数组的类型。
2.void*就是void指针,可以保存任何类型的指针,应为传入数组长度不知道,无法指定listA形参是指向什么长度的指针。就用void指针。
3.
打错了reinterpret_cast<int(*)>应该是reinterpret_cast<T(*)>
void *memcpy(void *dest, const void *src, size_t n);
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。
listB就是分配空间的起始位置,listA不就是要提取的数组,reinterpret_cast<T(*)>就是将原来的void*类型的listA指定为T []的三维数组指针,y,z不就是对应传入三维数组后两个[][]的大小,此时listA不就是想要得到的指针吗。然后在加上起始位置init_x,这个表达式就等于listA,size*sizeof(T)就是长度*T类型的所占的字节。也就是要提取数组的字节长。
4.详见http://bbs.fishc.com/forum.php?mod=viewthread&tid=72907&extra=page%3D1%26filter%3Dtypeid%26typeid%3D584。int*b可以指向一维数组,int (*b)就是二维,int (*b)这就是指向三维数组的指针。
int listB;当我什么也没说,这个可以。c99的VLA impossible 发表于 2016-8-21 10:51
1.template是一个模板,list_slices( a,3,3, 1,2, 0,2)会替换掉函数定义里面所有的T,如果你填入char就 ...
好详细呀,非常感谢 学到了很多知识{:10_275:} 2#正解。{:5_93:} list B 是栈里面的内存,函数结束之后这块内存会被释放,即此时该内存里值是未定义的。
用malloc 或者作为一个参数传进来。 int *p = (int *) malloc (len_x * len_y *3 +1);
页:
[1]