shuofxz 发表于 2016-8-19 16:28:43

自定义函数中传入三维数组

我想完成的是将一个三维数组取出其中的一部分
(我把三维数组想成一个三维的坐标系,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-19 16:28:44

本帖最后由 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:}

edc41113359 发表于 2016-8-20 02:40:57

listB[-2][-2]=listA,有问题

shuofxz 发表于 2016-8-20 08:57:47

edc41113359 发表于 2016-8-20 02:40
listB[-2][-2]=listA,有问题

额。。重点不在这里吧 =。=
而且for循环的初始值为init_x-1
for(int i=init_x-1; i<end_x; i++)

所以并不会出现为负数的情况

shuofxz 发表于 2016-8-20 08:59:19

@小甲鱼    小甲鱼老师求助{:10_302:}

impossible 发表于 2016-8-20 11:29:36

本帖最后由 impossible 于 2016-8-20 14:00 编辑

int listB;数组不支持这样吧

shuofxz 发表于 2016-8-20 16:11:20

impossible 发表于 2016-8-20 11:29
int listB;数组不支持这样吧

对的,这也是问题之一,但是每次调用函数的时候,x y都是不固定的,所以不能知道数组第一维和第二维的长度

有什么解决办法么?

cosmosh73 发表于 2016-8-21 00:22:50

看看

shuofxz 发表于 2016-8-21 08:30:27

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:51:19

本帖最后由 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

shuofxz 发表于 2016-8-21 22:49:31

impossible 发表于 2016-8-21 10:51
1.template是一个模板,list_slices( a,3,3, 1,2, 0,2)会替换掉函数定义里面所有的T,如果你填入char就 ...

好详细呀,非常感谢   学到了很多知识{:10_275:}

iszhuangsha 发表于 2016-8-22 11:59:37

2#正解。{:5_93:}

阁龙1427 发表于 2016-8-22 16:45:04

list B 是栈里面的内存,函数结束之后这块内存会被释放,即此时该内存里值是未定义的。
用malloc 或者作为一个参数传进来。

阁龙1427 发表于 2016-8-22 16:47:49

int *p = (int *) malloc (len_x * len_y *3 +1);
页: [1]
查看完整版本: 自定义函数中传入三维数组