从函数c返回二维数组的正确方法
我试过这个,但不起作用:从函数c返回二维数组的正确方法,c,arrays,function,C,Arrays,Function,我试过这个,但不起作用: #include <stdio.h> int * retArr() { int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; return a; } int main() { int a[3][3] = retArr(); return 0; } #包括 int*retArr() { int a[3][3]={{1,2,3},{4,5,6},{7
#include <stdio.h>
int * retArr()
{
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
int main()
{
int a[3][3] = retArr();
return 0;
}
#包括
int*retArr()
{
int a[3][3]={{1,2,3},{4,5,6},{7,8,9};
返回a;
}
int main()
{
int a[3][3]=retArr();
返回0;
}
我发现以下错误:
错误3错误C2075:“a”:数组初始化需要大括号4 IntelliSense:返回值类型与函数类型不匹配
我做错了什么?需要返回
int**
,而不是int
,以便:
int * retArr() {
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
该数组具有局部作用域,并且在退出该函数后立即销毁。这意味着返回a代码>实际上返回一个悬空指针
要解决此问题,请将数组放入全局范围,或使用malloc()
将数组复制到分配的空间中。结构是一种方法:
struct t_thing { int a[3][3]; };
然后按值返回结构
完整示例:
struct t_thing {
int a[3][3];
};
struct t_thing retArr() {
struct t_thing thing = {
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
};
return thing;
}
int main(int argc, const char* argv[]) {
struct t_thing thing = retArr();
...
return 0;
}
你面临的典型问题是inta[3][3]={{1,2,3},{4,5,6},{7,8,9}示例中的code>指函数返回后回收的内存。这意味着您的调用者阅读(未定义的行为)是不安全的
其他方法包括将数组(调用者拥有的数组)作为参数传递给函数,或创建新的分配(例如使用malloc
)。结构很好,因为它可以消除许多陷阱,但它并不适合所有场景。当结构的大小不是常量或非常大时,可以避免使用按值结构。\include
#include <stdio.h>
int** retArr()
{
static int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
int main()
{
int** a = retArr();
return 0;
}
int**retArr()
{
静态int a[3][3]={{1,2,3},{4,5,6},{7,8,9};
返回a;
}
int main()
{
int**a=retArr();
返回0;
}
还可以将返回的变量指定为static。您还必须在main中将变量a声明为int**(而不是指定维度)。几个问题:
首先,不能通过函数调用初始化数组;语言定义根本不允许它。char
的数组可以用字符串文本初始化,例如
char foo[] = "This is a test";
wchar\u t
、char16\u t
或char32\u t
的数组可以使用宽字符串文字进行初始化,否则初始化器必须是大括号内的值列表
其次,你有一个类型不匹配;除非它是sizeof
或一元&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则“T
的N元素数组”类型的表达式将转换为“指向T
的指针”类型的表达式,表达式的值将是第一个元素的地址
在函数retArr
中,表达式中a
的类型为“int
的三元素数组的三元素数组”;根据上述规则,这将转换为“指向int
”或int(*)[3]
”类型的表达式:
int (*retArr())[3]
{
int a[3][3] = ...;
return a;
}
但正如布伦丹指出的那样,一旦
retArr
退出a
就不再存在;返回的指针值最终无效 我们可以通过使用堆内存/使用stdlib分配内存来解决这个问题:
使用stdlib分配内存可以由malloc和calloc完成
创建数组:
- 用于分配5行
- 用于在每个“i”行中分配5列
- 因此,我们创建了arr[5][5]
#include<stdio.h>
#include<stdlib.h>
int **return_arr()
{
int **arr=(int **)malloc(sizeof(int *)*5);
int i,j;
for(i=0;i<5;i++)//checking purpose
{
arr[i]=(int *)malloc(sizeof(int)*5);
for(j=0;j<5;j++)
{
arr[i][j]=i*10+j;
}
}
return arr;
}
int main()
{
int **now;
now=return_arr();
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",now[i][j]);
}
printf("\n");
}
return 0;
}
#包括
#包括
int**return\u arr()
{
int**arr=(int**)malloc(sizeof(int*)*5);
int i,j;
对于(i=0;i,在OP给出的示例中,将数组放在堆栈上是最容易的
#包括stdio.h
void retArr(a[][3]) {
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6;
a[2][0] = 7; a[2][1] = 8; a[2][2] = 9;
}
main() {
int a[3][3];
retArr(a);
}
是的,这不会使用return函数“返回”数组,但我想这不是问题的目的。数组a[][]确实会被加载,加载的a[][]在retArr()之后在main中可用调用时,不会覆盖任何内容。请说明您遇到的错误类型。您需要完全避免这种错误。您返回的是一个在离开作用域时未定义的本地堆栈变量的地址。指针不兼容只是伤口上的盐。出于兴趣,为什么要从函数返回2D数组?这里有could是这样做的一个很好的理由,但很可能不是这样做的……至少有两个原因是错误的:返回类型是int(*)[3]
,而不是int**
,并且当函数返回时数组就不存在了,所以指针值无效。@JohnBode:int**没有错,只是类型不太强。(但返回指向堆栈变量的指针肯定是错误的。)好吧,这就是为什么我贴出帖子问他遇到了什么样的错误。我发现了编译错误;我的答案是正确的。我还想说,在函数签名中处理指针比处理数组更好,但我明天会扩展这个,将指针指向包含9int
的内存区域,并假装它是正确的包含指向<代码> int >代码>的指针是非常不正确的。当数组较大时使用什么?例如,我需要双数组的44 K x 2。@ sGuangiaGa考虑通过参数传递一个结构或数组的引用,而不是返回一个值。如您可能猜到的,一个大的值能够耗尽(剩余的)。堆栈存储。在某些情况下,可以选择返回堆分配的结构或数组。不要在C中强制转换malloc
的结果。该函数返回指向包含9int
的内存区域的指针。假装它包含指向int
的指针是非常不正确的,并且
return arr;
#include<stdio.h>
#include<stdlib.h>
int **return_arr()
{
int **arr=(int **)malloc(sizeof(int *)*5);
int i,j;
for(i=0;i<5;i++)//checking purpose
{
arr[i]=(int *)malloc(sizeof(int)*5);
for(j=0;j<5;j++)
{
arr[i][j]=i*10+j;
}
}
return arr;
}
int main()
{
int **now;
now=return_arr();
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",now[i][j]);
}
printf("\n");
}
return 0;
}
void retArr(a[][3]) {
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6;
a[2][0] = 7; a[2][1] = 8; a[2][2] = 9;
}
main() {
int a[3][3];
retArr(a);
}