这里有一个解决方案,可能比您要求的要多一点。我为结构数组创建了一个新的结构体,它带有大小信息,并且创建了一些操作该“数组结构”而不是原始指针的函数。
我的解决方案假设您最终想要在运行时输入数组大小(您的原型中定义了数组大小;在这种情况下,您可以简单地定义在编译时已知大小的适当数组)。
“数组结构”
myTable
仅包含指向实际数据的指针。这使得它非常小,可以通过值传递。复制是浅层的:副本指向与原始相同的数据。(这样我们可以使用通过值获取表格的函数来填充表格,例如
fill_tbl(struct myTable tbl)
)
程序具有一个头文件
myStructArray.h
,其中包含结构定义和函数声明,一个实现文件
myStructArray.c
,其中包含函数实现以及一个
main.c
文件。
myStructArray.h
#ifndef MY_STRUCT_ARRAY_H
#define MY_STRUCT_ARRAY_H
#include <stdint.h>
struct mystruct {
char name[10];
int id;
int status;
};
struct myTable
{
size_t mXSz;
size_t mYSz;
struct mystruct* mStructs;
};
struct myTable createTable(size_t szX, size_t szY);
struct mystruct* getStructPtr(struct myTable tbl, size_t x, size_t y);
void show_struct(struct mystruct* s);
void show_table(struct myTable tbl);
void destroy_table(struct myTable tbl);
#endif
myStructArray.c
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "myStructArray.h"
#include <assert.h>
void show_struct(struct mystruct *s)
{
if (s->id) {
printf("OK, STATUS IS 1\n");
printf("name: ->%s<-\n", s->name? s->name : "Null");
printf("status: %i\n", s->status);
}
else {
printf("ERROR, STATUS IS NOT 1");
}
}
struct mystruct* getStructPtr(struct myTable tbl, size_t x, size_t y)
{
assert(x < tbl.mXSz&& y < tbl.mYSz);
return &tbl.mStructs[y * tbl.mXSz + x];
}
void show_table(struct myTable tbl)
{
for (size_t y = 0; y < tbl.mYSz; y++)
{
for (size_t x = 0; x < tbl.mXSz; x++)
{
printf("*************** x: %zu, y: %zu******\n", x, y);
show_struct(getStructPtr(tbl, x, y));
}
printf("\n");
}
}
struct myTable createTable(size_t szX, size_t szY)
{
struct myTable newTbl = {szX, szY, 0};
size_t byteSz = szX * szY * sizeof(struct mystruct);
newTbl.mStructs = (struct mystruct *) malloc(byteSz);
memset(newTbl.mStructs, 0, byteSz);
return newTbl;
}
void destroy_table(struct myTable tbl)
{
free(tbl.mStructs);
}
main.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "myStructArray.h"
void fill_tbl(struct myTable tbl)
{
for (size_t y = 0; y < tbl.mYSz; y++)
{
for (size_t x = 0; x < tbl.mXSz; x++)
{
struct mystruct* sp = getStructPtr(tbl, x, y);
sprintf(sp->name, "%zu/%zu", x, y);
sp->id = 1+ y*tbl.mXSz + x;
sp->status = 1;
}
}
}
void main(void)
{
int size_x, size_y;
printf("size_x size_y: ");
scanf("%i %i", &size_x, &size_y);
struct myTable tbl = createTable(size_x, size_y);
fill_tbl(tbl);
int x_selected, y_selected;
printf("x_selected y_selected: ");
scanf("%i %i", &x_selected, &y_selected);
struct mystruct *sPtr = getStructPtr(tbl, x_selected, y_selected);
strcpy(sPtr->name, "NAME");
sPtr->id = 1234;
sPtr->status = 1;
show_struct(getStructPtr(tbl, x_selected, y_selected));
show_table(tbl);
}
示例会话
第一行和第二行的"3 2"和"0 1"是用户输入的大小和索引,其余部分则为输出结果。
size_x size_y: 3 2
x_selected y_selected: 0 1
OK, STATUS IS 1
name: ->NAME<-
status: 1
*************** x: 0, y: 0******
OK, STATUS IS 1
name: ->0/0<-
status: 1
*************** x: 1, y: 0******
OK, STATUS IS 1
name: ->1/0<-
status: 1
*************** x: 2, y: 0******
OK, STATUS IS 1
name: ->2/0<-
status: 1
*************** x: 0, y: 1******
OK, STATUS IS 1
name: ->NAME<-
status: 1
*************** x: 1, y: 1******
OK, STATUS IS 1
name: ->1/1<-
status: 1
*************** x: 2, y: 1******
OK, STATUS IS 1
name: ->2/1<-
status: 1
X*Y
个结构体的存储空间。你应该从table定义中删除[X][Y],只执行一次分配,或者从分配中删除X*Y。 - tinman