[英]How to return 2D array in C with a function?
我在 C 中有两个二维数组。 我们称它们为 a[row][col] 和 b[row][col]。 我在数组 a 中生成了随机值。 现在我想编写一个 function 来计算值,返回二维数组,并且 output 将分配给数组 b(这是一个生命的护航游戏)。
#include <stdio.h>
#include <stdlib.h>
int row, col = 0;
//creates row boundary
int create_row_line()
{
printf("\n");
for (int i = 0; i < col; i++)
{
printf(" -----");
}
printf("\n");
}
//returns the count of alive neighbours
int count_alive_neighbours(int a[row][col], int r, int c)
{
int i, j, count = 0;
for (i = r - 1; i <= r + 1; i++)
{
for (j = c - 1; j <= c + 1; j++)
{
if ((i < 0 || j < 0) || (i >= row || j >= col) || (i == r && j == c))
{
continue;
}
if (a[i][j] == 1)
{
count++;
}
}
}
return count;
}
int print_state(int x[row][col]){
create_row_line();
for (int i = 0; i < row; i++)
{
printf(":");
for (int j = 0; j < col; j++)
{
printf(" %d :", x[i][j]);
}
create_row_line();
}
}
int count_values(int x[row][col]){
int y[row][col];
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
int neighbours_alive = count_alive_neighbours(x, i, j);
// printf("%d" ,neighbours_alive);
if ((x[i][j] == 0) && (neighbours_alive == 3))
{
y[i][j] = 1;
}
else if ((x[i][j] == 1) && (neighbours_alive == 3 || neighbours_alive == 2))
{
y[i][j] = 1;
}
else
{
y[i][j] = 0;
}
}
}
return y;
}
int main()
{
//change row and column value to set the canvas size
printf("Enter number of rows: ");
scanf("%d", &row);
printf("Enter number of cols: ");
scanf("%d", &col);
int a[row][col], b[row][col];
int i, j, neighbours_alive;
// generate matrix
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
a[i][j] = rand() % 2;
}
}
// print initial state
printf("Initial state:");
print_state(a);
char quit;
do {
printf("Press enter to print next generation. To quit, enter 'q'.");
scanf("%c", &quit);
int** b = count_values(a);
print_state(b);
int** a = b;
} while(quit != 'q');
return 0;
}
但是有一个错误。 我是一个可怜的 C 程序员,不知道应该怎么做才能获得理想的效果。 在将 output 从 function 分配给数组 b 之后,我想分配 a=b 并从中进行循环以生成下一代。
所以问题是如何将 C 中的一个二维数组的值分配给另一个数组,以及如何从 function 返回二维数组并将结果分配给现有的二维数组。 感谢您的任何帮助
一种简单但不高效的方法是您可以定义一个结构来保存二维数组。 然后你可以简单地从 function 中返回 struct object 并相互分配。
typedef struct {
int array[row][col];
} S2dArray;
S2dArray count_values(S2dArray x){
S2dArray y;
....
return y;
}
int main() {
S2dArray a, b;
....
b = count_values(a);
print_state(b);
a = b;
....
}
Arrays 是“不可修改的左值”,因此不能是赋值运算符的左参数。 要复制数组,只需使用memcpy()
。 例如:
int a[row][col], b[row][col];
memcpy(a, b, sizeof(int[row][col]));
返回一个数组是一个棘手的话题,尤其是在您使用可变长度 arrays 时。 它在线程中讨论。
您必须以void*
或在 2D arrays 的情况下返回指向数组的指针,可以返回指向未定义大小的数组的不完整类型的指针int(*)[]
。
此外,必须动态分配数组以将其生命周期延长到分配 function 结束之后。 记住在不再使用时释放 memory。
void* count_values(int x[row][col]){
int (*y)[col] = malloc(sizeof(int[row][col]));
...
return y;
}
int main() {
...
int (*b)[col] = count_values(a);
...
free(b);
}
您提到的错误应该包括一些非致命的运行时错误,因为函数被定义为返回一个值,但没有返回语句......
int create_row_line()
{
printf("\n");
for (int i = 0; i < col; i++)
{
printf(" -----");
}
printf("\n");
return 0;//added
}
要么使 function 原型void create_row_line()
,要么在底部添加一个return
语句。
“如何使用函数返回 C 中的二维数组”
一种方法是使用 VLA 排列将VLA数组作为参数传递。 这将允许更改 function 中的值,然后返回更新后的数组。 下面是一个通用的例子来说明。
请注意数组本身之前的数组大小的 position:
void populate2D(int x, int y, int (*arr)[x][y]);
int main(void)
{
int x=3, y=4;
int arr[x][y];
memset(arr, 0, sizeof arr);//initialize array
populate2D(x, y, &arr);//passing array sizes, and pointer to array
return 0;
}
void populate2D(int x, int y, int (*arr)[x][y])
{
for(int i=0;i<x;i++)
{
for(int j = 0;j<y;j++)
{
(*arr)[i][j] = i*j;
}
}
}
Arrays 对象不能分配给、从函数返回或作为 function 调用的参数传递。 在后一种情况下,function 调用参数被转换为指向第一个元素的指针,并且声明为 T 类型数组的 function 参数被“调整”为指向 T 类型的指针(因此void foo(int a[6])
是调整为void foo(int *a)
,例如)。
由于main
已经有两个 arrays a
和b
您可以将它们都传递给count_values
,更改count_values
以接受两个 arrays ,如下所示:
void count_values(const int x[row][col], int y[row][col])
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
/* put next generation in y[i][j] here */
}
}
}
并从main
中调用它,如下所示:
count_values(a, b);
print_state(b);
memcpy(b, a, sizeof(a));
(注意: memcpy
由#include <string.h>
声明。)
而不是每次都将a
复制到b
,您可以拥有一个 3-D 数组int a[2][row][col];
并为每一代翻转a[0]
和a[1]
的用法:
int flip = 0;
int a[2][row][col];
int i, j, neighbours_alive;
// generate matrix
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
a[flip][i][j] = rand() % 2;
}
}
// print initial state
printf("Initial state:");
print_state(a[flip]);
char quit;
do {
printf("Press enter to print next generation. To quit, enter 'q'.");
scanf("%c", &quit);
// a[flip] contains the current generation,
// a[1-flip] will contain the next generation.
b = count_values(a[flip], a[1-flip]);
// flip the usage of a[0] and a[1]
flip = 1 - flip;
// a[1-flip] now contains the previous generation
// a[flip] now contains the new current generation
print_state(a[flip]);
} while(quit != 'q');
一个可能的改进是将行数和列数传递为 function arguments 而不是使用全局变量:
void create_row_line(int col)
{
/* print stuff */
}
int count_alive_neighbours(int row, int col, const int a[row][col], int r, int c)
{
int count = 0;
/* count neighbours */
return count;
}
void print_state(int row, int col, const int x[row][col])
{
/* print state */
}
void count_values(int row, int col, const int x[row][col], int y[row][col])
{
/* put next generation in y */
}
对应的 function 调用:
create_row_line(col);
int neighbours_alive = count_alive_neighbours(row, col, x, i, j);
print_state(row, col, a[flip]);
count_values(row, col, a[flip], a[1-flip]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.