我是C的新手。
我有一个二维结构数组,其大小为i,j是在运行时确定的。
我想将此数组作为参数传递给函数并迭代所有元素。
以下是代码的原型:
typedef struct obj {
char id[10];
int value;
} Object;
我尝试了以下但是它没有工作:
int sum_all_elements(Object *obj_ptr);
int main() {
int i, j; //gotten from user input which I omitted
Object o[i][j];
int total = sum_all_elements(&o);
}
传递o [i] [j]的正确方法是什么,以及如何在函数中迭代它?
另外,我想创建更新2D数组中元素的函数,有没有一种方法可以在函数中进行更改,并且当我从函数返回时效果仍然存在?
答案 0 :(得分:1)
使用typedef
,如下所示:
enum { IDL = 10 };
typedef struct {
char id[IDL];
int value;
} obj;
如果您打算使用2D VLA,那么最好考虑传递第一行的地址,而不是第一行的地址。 (尽管这两个地址是一样的)为什么?将数组(例如obj o[i][j];
)作为参数传递给函数时,将第一级间接转换为指针(例如obj o[i][j]
变为obj (*o)[j]
)。
以main
中声明的VLA为例,如下所示:
obj o[i][j]; /* declare VLA */
所以你的函数声明需要匹配(并且因为列数是非常量的,所以是正确的顺序)例如:
int sum_all_elements (int i, int j, obj (*obj_ptr)[j]);
然后,您可以在程序中调用该函数,例如:
printf ("\n sum : %d\n\n", sum_all_elements (i, j, &o[0]));
这相当于:
printf ("\n sum : %d\n\n", sum_all_elements (i, j, o));
将一个简短示例放在一起(并填充obj[a][b].value = a + b;
),您可以执行类似以下操作:
#include <stdio.h>
enum { IDL = 10 };
typedef struct {
char id[IDL];
int value;
} obj;
int sum_all_elements (int i, int j, obj (*obj_ptr)[j]);
int main (void) {
int i, j;
printf ("\n enter i & j: ");
if (scanf (" %d %d", &i, &j) != 2) {
fprintf (stderr, "error: invalid input, i, j.\n");
return 1;
}
obj o[i][j]; /* declare VLA */
for (int a = 0; a < i; a++)
for (int b = 0; b < j; b++)
o[a][b].value = a + b; /* fill value with misc a + b */
printf ("\n sum : %d\n\n", sum_all_elements (i, j, o));
return 0;
}
/* some all .value for i x j array of obj */
int sum_all_elements (int i, int j, obj (*obj_ptr)[j])
{
int sum = 0;
for (int a = 0; a < i; a++)
for (int b = 0; b < j; b++)
sum += obj_ptr[a][b].value;
return sum;
}
示例使用/输出
$ ./bin/p2p2a
enter i & j: 10 10
sum : 900
答案 1 :(得分:0)
如果您使用的是C99或更高版本,则可以使用VLA来完成此操作。以下示例要求用户输入id
结构的value
和Object
字段的信息,然后调用函数以显示2d VLA的内容:< / p>
#include <stdio.h>
typedef struct obj {
char id[10];
int value;
} Object;
void show_obj(int rows, int cols, Object arr[rows][cols]);
int main(void)
{
int num_rows, num_cols;
int row, col;
num_rows = 3;
num_cols = 3;
Object obj_arr[num_rows][num_cols];
for (row = 0; row < num_rows; row++)
for (col = 0; col < num_cols; col++) {
printf("Element [%d][%d]:\n", row, col);
printf(" enter id: ");
scanf("%9s", obj_arr[row][col].id);
printf(" enter value: ");
scanf("%d", &(obj_arr[row][col].value));
}
show_obj(num_rows, num_cols, obj_arr);
return 0;
}
void show_obj(int num_rows, int num_cols, Object obj_arr[num_rows][num_cols])
{
int row, col;
for (row = 0; row < num_rows; row++)
for (col = 0; col < num_cols; col++) {
printf("Element [%d][%d]:\n", row, col);
printf(" id: %s\n", obj_arr[row][col].id);
printf(" value: %d\n", obj_arr[row][col].value);
}
}
将VLA传递给函数时,请注意必须先传递数组的尺寸。
另一种方法是为结构手动分配内存,然后模拟2d数组。您可以为指向Object
结构的指针的多个指针分配空间。这些指针中的每一个都指向一行Object
结构的第一个Object
,因此您可以在每行中分配空间来存储Object
。以下代码演示了第二种方法。设置完成后,obj_arr
被访问并传递,就好像它是一个二维数组一样。这种方法的一个缺点是您需要手动释放内存分配。但是,这种方法适用于C99之前的编译器:
#include <stdio.h>
#include <stdlib.h>
typedef struct obj {
char id[10];
int value;
} Object;
void show_obj(Object **arr, int rows, int cols);
int main(void)
{
int num_rows, num_cols;
int row, col;
num_rows = 3;
num_cols = 3;
Object **obj_arr = malloc(sizeof(Object *) * num_rows);
for (row = 0; row < num_rows; row++)
obj_arr[row] = malloc(sizeof(Object) * num_cols);
for (row = 0; row < num_rows; row++)
for (col = 0; col < num_cols; col++) {
printf("Element [%d][%d]:\n", row, col);
printf(" enter id: ");
scanf("%9s", obj_arr[row][col].id);
printf(" enter value: ");
scanf("%d", &(obj_arr[row][col].value));
}
show_obj(obj_arr, num_rows, num_cols);
/* Free allocated memory */
for (row = 0; row < num_rows; row++)
free(obj_arr[row]);
free(obj_arr);
return 0;
}
void show_obj(Object **obj_arr, int num_rows, int num_cols)
{
int row, col;
for (row = 0; row < num_rows; row++)
for (col = 0; col < num_cols; col++) {
printf("Element [%d][%d]:\n", row, col);
printf(" id: %s\n", obj_arr[row][col].id);
printf(" value: %d\n", obj_arr[row][col].value);
}
}
答案 2 :(得分:-2)
你绝对肯定你需要:
我建议使用«linear»数组并通过malloc()
(或calloc()
分配内存,如果你想在创建时进行零初始化)。这样的事情:
Object *o;
o = (Object*)calloc(i * j, sizeof(Object));
... (doing something with o)
int total = sum_all_elements(o, i, j);
... (now it is time to free the allocated memory)
free(o);
o = 0;
int sum_all_elements(Object *obj_ptr, int i, int j) {
int x, y, s;
for (s = y = 0; y < j; y++)
for (x = 0; x < i; x++) {
s += obj_ptr[j * y + x].value;
}
return s;
}