在C语言中如何返回一个二维数组?

在C语言中如何返回一个二维数组?

C语言中对待数组的方式与大多数其他语言不同;如果你想在C语言中使用数组,需要理解以下概念。

除非它是sizeof或一元运算符&的操作数,或者是一个字符串字面值用于在声明中初始化另一个数组时,类型为“N元素数组 of T”的表达式将被转换(“衰减”)为类型为“指向T的指针”的表达式,表达式的值将是数组的第一个元素的地址。这个结果不是lvalue;它不能成为赋值的目标,也不能成为++或--运算符的操作数。

这就是为什么你不能定义一个返回数组类型的函数;数组表达式将在return语句中转换为指针类型,而且无论如何都没有办法将结果分配给另一个数组表达式。

信不信由你,这背后有一个坚实的技术原因;当Dennis Ritchie最初开发C语言时,他从B编程语言借鉴了许多概念。B是一种“无类型”语言;所有东西都存储为无符号单词或“单元格”。内存被视为线性数组的“单元格”。当你声明一个数组时

auto arr[N];

B 为数组内容预留了 N 个“单元格”,另外还有一个绑定到 `arr` 的单元格用于存储第一个元素的偏移(基本上是一个指针,但没有任何类型语义)。数组访问被定义为 `*(arr+i)`;你需要从存储在 `a` 中的地址偏移 `i` 个单元格并解引用结果。这对于 C 来说非常有效,直到 Ritchie 开始向语言中添加结构体类型。他希望结构体的内容不仅可以抽象地描述数据,还可以物理地表示位。他使用的示例类似于:

struct {

int node;

char name[14];

};

他想为节点保留2个字节,紧随其后的是14个字节的名称元素。他希望这样的结构数组被布置出来,使得你有2个字节,接着是14个字节,然后是2个字节,接着是14个字节等等。他无法找到一个好的方法来处理数组指针,所以他完全摆脱了它。C语言不是设置指针存储,而是根据数组表达式自行计算。这就是为什么你不能对数组表达式赋值的原因;没有东西可以赋值给它。

那么,如何从函数返回一个二维数组?

你不能。你可以返回一个指向二维数组的指针,例如:

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] = ...;

}

您可以将内存分配成类似于二维数组的形式,但是行不一定是连续的:

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)

相关文章

倒卖是什么意思?违法行为界定与案例警示
365bet中文版app

倒卖是什么意思?违法行为界定与案例警示

🕒 10-14 👁️ 3311
AG账户充值流程
谁有365体育投注网站

AG账户充值流程

🕒 02-06 👁️ 386
100米男子奥运纪录(100米男子奥运纪录是多少秒)
微信账号注销教程
365bet官网

微信账号注销教程

🕒 10-27 👁️ 2326
ofo上线车辆数据管理平台向政府开放,上海成首批接入城市
七步诗是什么意思
365bet官网

七步诗是什么意思

🕒 01-27 👁️ 7757
屏幕刷新率多少合适,解析最佳刷新率选择
谁有365体育投注网站

屏幕刷新率多少合适,解析最佳刷新率选择

🕒 07-14 👁️ 759
疯狂棋牌
365bet中文版app

疯狂棋牌

🕒 07-05 👁️ 4528
美德乐奶瓶(3个装)怎么样
365bet中文版app

美德乐奶瓶(3个装)怎么样

🕒 08-23 👁️ 4066