从函数c返回二维数组的正确方法

时间:2012-11-15 02:05:31

标签: 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;
    }

我收到这些错误:

  

错误3错误C2075:'a':数组初始化需要大括号
    4 IntelliSense:返回值类型与功能类型

不匹配

我做错了什么?

7 个答案:

答案 0 :(得分:7)

结构是一种方法:

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;
}

您遇到的典型问题是示例中的int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};指的是在函数返回后回收的内存。这意味着调用者读取(未定义的行为)是不安全的。

其他方法涉及将数组(调用者拥有的)作为参数传递给函数,或者创建新的分配(例如使用malloc)。结构很好,因为它可以消除许多陷阱,但它并不适合每种情况。当结构的大小不是常数或非常大时,您将避免使用struct by value。

答案 1 :(得分:1)

#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;
}

您还可以将返回的变量指定为static。您还必须将main中的变量a声明为int **(而不是指定维度)。

答案 2 :(得分:1)

几个问题:

首先,您无法从函数调用初始化数组;语言定义根本不允许它。可以使用字符串文字初始化char数组,例如

char foo[] = "This is a test";

wchar_tchar16_tchar32_t的数组可以使用宽字符串文字进行初始化,但初始化程序必须是括号括起的值列表。

其次,你的类型不匹配;除非它是sizeof或一元&运算符的操作数,或者是一个字符串文字用于初始化声明中的另一个数组,表达式为“N元素数组{{1 “将被转换为类型为”T指针“的表达式,表达式的值将是第一个元素的地址;

在函数T中,表达式中retArr的类型是“3元素数组a的3元素数组”;根据上面的规则,这将转换为“指向int的3元素数组的指针”或int的表达式:

int (*)[3]

但正如Brendan指出的那样,int (*retArr())[3] { int a[3][3] = ...; return a; } 退出retArr后不再存在;返回的指针值无效。

答案 3 :(得分:1)

我们可以通过使用stdlib分配堆内存/内存来解决它:

  

使用stdlib分配内存可以通过malloc和calloc完成。

     

创建数组

  • int  ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 ); 
    
    用于分配5行。
  • arr[i]=(int *)malloc(sizeof(int)*5);
    
    用于在每个&#34; i&#34;中分配5列。行。
  • 因此我们创建了arr [5] [5]。
  

返回数组:

  • 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;
}

答案 4 :(得分:0)

在OP给出的示例中,最简单的方法是将数组放在堆栈上。我没有测试过,但是会是这样。

#include 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 [] []确实已加载,并且在调用retArr()之后,已加载的a [] []在main中可用,没有任何内容被覆盖。

答案 5 :(得分:-1)

为此:

int * retArr() {
    int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
    return a;
}

数组具有本地范围,并在退出函数后立即销毁。这意味着return a;实际上返回一个悬空指针。

要解决此问题,请将数组放在全局范围内,或使用malloc()并将数组复制到已分配的空间中。

答案 6 :(得分:-3)

需要返回int**,而不是int