在C中返回二维数组?

Mathias Lykkegaard洛伦岑

我最近开始编程C只是为了好玩。我在一个非常熟练的程序员C# .NETJava台式机领域内,但这是谈到了有点太挑战我。

我正在尝试做一些“简单”的事情,就像从函数中返回二维数组一样。我曾尝试在网络上对此进行研究,但是很难找到可行的方法。

到目前为止,这就是我所拥有的。它并没有完全返回数组,而是只填充了一个。但是即使那样也无法编译(如果您是熟练的C程序员,我相信原因对于您来说必须显而易见)。

void new_array (int x[n][n]) {
  int i,o;

  for (i=0; i<n; i++) {
      for (o=0; o<n; o++) {
        x[i][o]=(rand() % n)-n/2;
      }
  }

  return x;
}

和用法:

int x[n][n];
new_array(x);

我究竟做错了什么?应该提到的n是一个具有值的常数3

编辑:尝试定义常量时,这是编译器错误:http : //i.imgur.com/sa4JkXs.png

约翰·波德

C不像大多数语言一样对待数组;如果要在C中使用数组,则需要了解以下概念。

除了当它是的操作数sizeof或一元&运算符,或者是字面被用来在声明另一阵列,初始化一个字符串表达型“的N元件阵列的T将被转换(“衰变”)”到的表达键入“ pointer to T”,则表达式的值将为数组第一个元素的地址。这个结果不是左值;它既不能是赋值的目标,也不能是++--运算符的操作数

这就是为什么您不能定义一个函数来返回数组类型的原因。数组表达式将作为return语句的一部分转换为指针类型,此外,无论如何都无法将结果分配给另一个数组表达式。

信不信由你,这是有充分的技术理由的。最初开发C时,Dennis Ritchie借鉴了B编程语言的许多概念。B是一种“无类型”语言;一切都存储为一个无符号的单词或“单元格”。内存被视为“单元”的线性阵列。当您将数组声明为

auto arr[N];

B将为数组内容留出N个“单元”,并绑定一个附加单元arr以存储到第一个元素的偏移量(基本上是一个指针,但没有任何类型语义)。数组访问定义为*(arr+i)i从存储在其中的地址偏移了单元格a并取消了对结果的引用。这对于C语言非常有效,直到Ritchie开始向该语言添加结构类型为止。他希望结构的内容不仅可以抽象地描述数据,而且可以物理地表示位。他用的例子是

struct {
  int node;
  char name[14];
};

他想为节点预留2个字节,紧随其后的是为name元素预留14个字节。并且他希望布置这样一个结构的数组,以便您有2个字节,然后是14个字节,然后是2个字节,然后是14个字节,依此类推。他想不出一种处理数组指针的好方法,因此他完全摆脱了它。C不用为指针留出存储空间,而是简单地从数组表达式本身计算指针。这就是为什么您不能为数组表达式分配任何内容的原因。没有什么可将值分配

那么,如何从函数返回2D数组呢?

你不知道 可以返回一个指向2D数组指针,例如:

T (*func1(int rows))[N]
{
  T (*ap)[N] = malloc( sizeof *ap * rows );
  return ap;
}

这种方法的缺点是N必须在编译时就知道。

如果使用支持可变长度数组的C99编译器或C2011编译器,则可以执行以下操作:

void func2( size_t rows, size_t cols, int (**app)[cols] ) 
{
  *app = malloc( sizeof **app * rows );
  (*app)[i][j] = ...;                   // the parens are necessary
  ...
 }

如果没有可用的可变长度数组,那么至少列维必须是编译时常量:

#define COLS ...
...
void func3( size_t rows, int (**app)[COLS] )
{ 
  *app = malloc( sizeof **app * rows );
  (*app)[i][j] = ...;
}

您可以将内存零碎分配给类似于2D数组的对象,但是行不一定是连续的:

int **func4( size_t rows, size_t cols )
{
  int **p = malloc( sizeof *p * rows );
  if ( p )
  {
    for ( size_t i = 0; i < rows; i++ )
    {
      p[i] = malloc( sizeof *p[i] * cols );
    }
  }
  return p;
}

p阵列; 它指向指向的一系列指针int出于所有实际目的,您可以像使用2D数组一样使用它:

 int **arr = foo( rows, cols );
 ...
 arr[i][j] = ...;
 printf( "value = %d\n", arr[k][l] );

注意,C没有任何垃圾回收;您负责清理自己的混乱情况。在前三种情况下,很简单:

int (*arr1)[N] = func(rows);
// use arr[i][j];
...
free( arr1 );

int (*arr2)[cols];
func2( rows, cols, &arr2 );
...
free( arr2 );

int (*arr3)[N];
func3( rows, &arr3 );
...
free( arr3 );

在最后一种情况下,由于执行了两步分配,因此需要进行两步取消分配:

int **arr4 = func4( rows, cols );
...
for (i = 0; i < rows; i++ )
  free( arr4[i] )
free( arr4)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在C中返回二维数组

来自分类Dev

如何在C ++中返回二维数组

来自分类Dev

C中的二维数组错误

来自分类Dev

反转C ++中的二维数组

来自分类Dev

在C中释放二维数组

来自分类Dev

在C中打印二维数组

来自分类Dev

计算二维数组中的值并返回坐标

来自分类Dev

从webmethod返回javascript中的二维数组

来自分类Dev

如何从cpp中的函数返回二维数组

来自分类Dev

将指针返回二维数组[C ++]

来自分类Dev

C#从函数返回二维数组索引

来自分类Dev

从C函数返回指向二维数组的指针

来自分类Dev

如何让c++将二维数组返回给python

来自分类Dev

如何在C中返回静态分配的二维数组?

来自分类Dev

在C ++中打印出返回地址值的二维数组的函数

来自分类Dev

在 C++ 中返回二维数组对角线元素总和的函数

来自分类Dev

返回二维数组的索引

来自分类Dev

过滤二维数组/返回ArrayIndexOutofBoundException

来自分类Dev

ANSI C中内存中的二维数组

来自分类Dev

在C ++中访问二维指针数组中的值

来自分类Dev

C / C ++中的二维字符数组

来自分类Dev

来自 C# 的 Objective C 中的二维数组

来自分类Dev

c ++函数创建一个二维数组并返回一个指向二维数组的指针

来自分类Dev

在二维数组中搜索一维数组的索引,并逐行返回java

来自分类Dev

按位| 在二维数组C中

来自分类Dev

在C#中对更大的二维数组进行排序

来自分类Dev

来自C中数据文件的二维数组

来自分类Dev

C ++中的二维数组构造混乱

来自分类Dev

在C ++中初始化二维对象数组