首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >声明C函数以返回数组

声明C函数以返回数组
EN

Stack Overflow用户
提问于 2009-09-21 08:26:04
回答 5查看 90.8K关注 0票数 47

如何创建一个返回数组的函数?我试过了

代码语言:javascript
运行
复制
const int WIDTH=11;
const int HEIGHT=11;

int main() {
  char A[WIDTH][HEIGHT];
  A=rand_grid(WIDTH,HEIGHT);
  return 0;
}

// Initializes a random board.
char[][] rand_grid(int i, int k) {
  char* A[i][k];
  for(j=0;j<i;++j) {
    for(l=0;l<k;++l) {
      A[j][l]=ran(10);
    }
  }
  return A;
}

// Returns a random number from the set {0,...,9}.
int ran(int i) {
  srand((unsigned int) time(0));
  return(rand()%10);
}
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-09-21 15:05:47

需要指出的几件事。

首先,您不能像在这里那样分配数组对象:

代码语言:javascript
运行
复制
char A[WIDTH][HEIGHT];  
A=rand_grid(WIDTH,HEIGHT);

数组类型的对象不可修改。

其次,C中的函数不能返回数组类型。不过,它们可以返回指向数组的指针:

代码语言:javascript
运行
复制
char (*foo(int width))[HEIGHT]
{
  /**
   * dynamically allocate memory for a widthxHEIGHT array of char
   */
  char (*newArr)[HEIGHT] = malloc(sizeof *newArr * width);
  /**
   * initialize array contents here
   */
  return newArr;
}

语法有点混乱;它看起来像这样

代码语言:javascript
运行
复制
       foo                                   -- foo
       foo(int width)                        -- is a function
                                             -- taking an int parameter
      *foo(int width)                        -- returning a pointer
     (*foo(int width))[HEIGHT]               -- to a HEIGHT-element array
char (*foo(int width))[HEIGHT]               -- of char

对于C89,上述代码段中的高度必须是编译时常量整数表达式(宏、数值文字或由宏和/或数值文字组成的算术表达式)。我不确定这是否也适用于C99。

根据您发布的代码片段,您要做的是获取一个已分配的数组并初始化其内容。请记住,在大多数上下文中,数组类型的表达式将隐式转换为指向基类型的指针。也就是说,如果你将T的N元数组传递给一个函数,那么这个函数实际接收的是一个指向T的指针:

代码语言:javascript
运行
复制
void foo (T *p) {...}
...
T arr[N];
foo(arr);

对于2-d数组,它有一点丑陋:

代码语言:javascript
运行
复制
void foo (T (*p)[M]) {...}
...
T arr[N][M];
foo(arr);

这也依赖于M在编译时是已知的,这限制了函数的有用性。你想要的是一个可以处理任意大小的二维数组的函数。据我所知,完成此操作的最好方法不是传递指向数组的指针,而是传递array1中第一个元素的地址,并将行数和列数作为单独的参数传递:

代码语言:javascript
运行
复制
void foo(T *base, size_t rows, size_t cols) {...}
...
T arr[N][M];
foo (&arr[0][0], N, M);

因此,您的rand_grid函数将如下所示:

代码语言:javascript
运行
复制
void rand_grid(char *base, size_t rows, size_t cols)
{
  size_t i, j;
  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < cols; j++)
    {
      /**
       * Since base is a simple char *, we must index it
       * as though it points to a 1-d array.  This works if
       * base points to the first element of a 2-d array,
       * since multi-dimensional arrays are contiguous.  
       */
      base[i*cols+j] = initial_value();
    }
  }
}

int main(void)
{
  char A[WIDTH][HEIGHT];
  rand_grid(&A[0][0], WIDTH, HEIGHT);
  ...
}

  1. 尽管表达式&A[0][0]A产生相同的值(A的基地址),但这两个表达式的类型是不同的。第一个表达式的计算结果是指向char ( (char (*)[HEIGHT]).

)的简单指针,而第二个表达式的计算结果是指向二维char数组的指针(char *

票数 77
EN

Stack Overflow用户

发布于 2009-09-21 08:27:59

你不能。你可以将指针作为参数传递给数组并让函数修改它,或者函数本身可以分配数据并返回指针。

在你的情况下

代码语言:javascript
运行
复制
void rand_grid(char A[WIDTH][HEIGHT]) {
    A[0][0] = 'A'; // or whatever you intend to do
}

main() {
    char A[WIDTH][HEIGHT];
    rand_grid(A);
}

编辑:正如caf指出的那样,人们实际上可以返回一个包含数组的struct,但当然没有哪个头脑正常的C程序员会这样做。

票数 15
EN

Stack Overflow用户

发布于 2009-09-21 08:27:44

除了原始(值)类型之外,您永远不能返回堆栈分配的("auto")变量,以及类似的值。对于其他类型,您需要使用malloc()从堆中分配内存,或者将(固定大小)数组包装到struct中。

如果您使用固定大小的数组,则可以将其建模为struct并使用struct-return:

代码语言:javascript
运行
复制
#define WIDTH  11
#define HEIGHT 11

typedef struct {
  unsigned char cell[WIDTH * HEIGHT];
} Board;

Board board_new(void)
{
  Board b;
  size_t i;

  for(i = 0; i < sizeof b.cell / sizeof *b.cell; i++)
    b.cell[i] = rand() & 255;
  return b;
}

这很好,而且不应该比使用显式指针的替代方案代价更高:

代码语言:javascript
运行
复制
void board_init(Board *b);

因为前者的struct-return可以(由编译器)重写为后者。这称为return value optimization

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1453410

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档