C 从函数返回的衰减多维数组
与之相关,是否有一种方法可以从函数返回所谓的“衰减数组指针”?总之(假设2维数组)返回C 从函数返回的衰减多维数组,c,arrays,pointers,C,Arrays,Pointers,与之相关,是否有一种方法可以从函数返回所谓的“衰减数组指针”?总之(假设2维数组)返回int(*a)[5]格式而不是int**格式 据我所知,当返回的int**指针被发送到另一个等待(int*)[]参数的函数时,它工作不正常。是的,但语法看起来不太好 int(*f())[5] { static int a[1][5] = { { 1, 2, 3, 4, 5 } }; return a; } 基本上,它只是由f()(一个函数)替换的a。使用typedef,它变得更可读 typedef i
int(*a)[5]
格式而不是int**
格式
据我所知,当返回的
int**
指针被发送到另一个等待(int*)[]
参数的函数时,它工作不正常。是的,但语法看起来不太好
int(*f())[5] {
static int a[1][5] = { { 1, 2, 3, 4, 5 } };
return a;
}
基本上,它只是由f()
(一个函数)替换的a
。使用typedef,它变得更可读
typedef int inner_array[5];
inner_array *f() {
// like before ...
}
请注意,要表示Abstract类型,而不使用名称,您需要编写int(*)[5]
。也就是说,您只需删除名称<代码>(int*)[5]是无效的语法
您是对的-您不能返回int**
,因为这意味着您有一个指向指针的指针。使用f()。但事实上,您返回的数组指针只指向一个内存块,因此如果要进行两次间接寻址,您将尝试将数据重新解释为指针
相反,如果返回aint(*)[5]
并执行f()[a][B]
操作,则不会从指针返回的地址读取任何值。相反,您只需将偏移量A
添加到地址,并将类型从int(*)[5]
调整为int[5]
,以便在调整后的地址处具有引用内存的数组。然后,下一个索引将再次通过B
进行调整,并且由于它在int*
上运行(在数组衰减之后),不再在数组指针上运行,因此它将读取存储在调整后的地址处的内容,以最终生成int
。这是非数组指针和数组指针的一个重要区别
如果你愿意的话,你可以尝试一下。考虑这两个片段。一个可能会崩溃,但另一个可能不会(但两者都会产生未定义的行为,因此不应在实际程序中进行此操作)
是的,但是语法看起来不太好
int(*f())[5] {
static int a[1][5] = { { 1, 2, 3, 4, 5 } };
return a;
}
基本上,它只是由f()
(一个函数)替换的a
。使用typedef,它变得更可读
typedef int inner_array[5];
inner_array *f() {
// like before ...
}
请注意,要表示Abstract类型,而不使用名称,您需要编写int(*)[5]
。也就是说,您只需删除名称<代码>(int*)[5]
是无效的语法
您是对的-您不能返回int**
,因为这意味着您有一个指向指针的指针。使用f()。但事实上,您返回的数组指针只指向一个内存块,因此如果要进行两次间接寻址,您将尝试将数据重新解释为指针
相反,如果返回aint(*)[5]
并执行f()[a][B]
操作,则不会从指针返回的地址读取任何值。相反,您只需将偏移量A
添加到地址,并将类型从int(*)[5]
调整为int[5]
,以便在调整后的地址处具有引用内存的数组。然后,下一个索引将再次通过B
进行调整,并且由于它在int*
上运行(在数组衰减之后),不再在数组指针上运行,因此它将读取存储在调整后的地址处的内容,以最终生成int
。这是非数组指针和数组指针的一个重要区别
如果你愿意的话,你可以尝试一下。考虑这两个片段。一个可能会崩溃,但另一个可能不会(但两者都会产生未定义的行为,因此不应在实际程序中进行此操作)
不过,你真的走错了路
尽管如此,您的做法确实是错误的。有没有可能看到一些代码?请注意,接受int*[]
的函数实际上是接受int**
。问题是2D数组不是int**
,也就是说,从一个函数返回2D数组是正确的(因为它表示内部数据),但不能用作函数的参数void(f*a[])
是否有可能看到一些代码?请注意,函数取int*[]
实际上正在使用int**
。问题在于2D数组不是int**
,也就是说,从一个函数返回2D数组是正确的(因为它表示内部数据),但不能用作函数的参数void(f*a[])