9

我已经尝试过了,但它不起作用:

#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: 返回值类型与函数类型不匹配

我究竟做错了什么?

4

7 回答 7

8

结构是一种方法:

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}};在您的示例中是指在函数返回后回收的内存。这意味着您的调用者读取 (Undefined Behaviour) 是不安全的。

其他方法包括将数组(调用者拥有的)作为参数传递给函数,或者创建一个新的分配(例如使用malloc)。该结构很好,因为它可以消除许多陷阱,但它并不适合所有场景。当结构的大小不是恒定的或非常大时,您将避免按值使用结构。

于 2012-11-15T02:11:38.593 回答
4

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

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

创建数组

  • int  ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 ); 
    
    用于分配 5 行。
  • arr[i]=(int *)malloc(sizeof(int)*5);
    
    用于在每个“i”行中分配 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;
}
于 2017-05-17T18:46:04.257 回答
2

几个问题:

首先,您不能从函数调用中初始化数组;语言定义根本不允许这样做。可以用字符串字面量初始化一个数组char,例如

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

wchar_t一个, char16_t, 或的数组char32_t可以使用宽字符串字面量进行初始化,否则初始化程序必须是用大括号括起来的值列表。

其次,您的类型不匹配;除非它是sizeof或一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of T”类型的表达式将转换为“pointer to T”类型的表达式,表达式的值将是第一个元素的地址;

在函数中retArr,表达式中的类型a为“3-element array of 3-element array of int”;根据上面的规则,这将被转换为“指向 3 元素数组的指针”类型的表达式int,或者int (*)[3]

int (*retArr())[3]
{
  int a[3][3] = ...;
  return a;
}

但正如 Brendan 指出的那样,一旦retArr退出a不再存在;返回的指针值最终无效。

于 2012-11-15T02:32:45.687 回答
-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;
}

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

于 2012-11-15T02:20:07.247 回答
-1

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

是的,这不会使用返回函数“返回”数组,但我认为这不是问题的意图。数组 a[][] 确实被加载了,加载的 a[][] 在调用 retArr() 后在 main 中可用,没有任何内容被覆盖。

于 2019-04-30T22:56:00.610 回答
-2

为了这:

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

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

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

于 2012-11-15T02:11:02.543 回答
-5

需要退货int**,没有int

于 2012-11-15T02:06:51.133 回答