嵌套结构数组
Array of nested structures
我有巨大的嵌套结构数组,这使得无法分配那种 space 并迫使我使用堆。但是我在使用 malloc
时遇到了困难。
问题的要点如下。
struct year_of_joining
{
struct district
{
struct colleges
{
struct departments
{
struct sections
{
struct students
{
int sex;
}student[100];
}section_no[8];
}department_no[17];
}college[153];
}dist[13];
};
如果我用
int main()
{
int i=0;
struct year_of_joining** year;
year = malloc(100 * sizeof(struct year_of_joining));
for (i = 0; i < 100; i++)
{
year[i] = malloc(sizeof(struct year_of_joining));
}
year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex = 1;//works fine
printf("%d", year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex);//prints 1
free(year);
return 0;
}
它工作正常但是当我像 year_of_joining 创建一个指向 dist 的指针并使用间接运算符时它不编译:
year[1]->dist[2]->college[0].department_no[0].section_no[0].student[8].sex = 9;//error C2039: 'dist' : is not a member of 'year_of_joining'
我该如何解决这个问题?我走对了吗?
你的方向不对。您的结构非常庞大,如果输入的大小(例如学生人数)太大,您将需要重新编译程序。
我建议您将数据建模为可以单独分配的较小结构,也许使用指针或 ID 号将它们 link 在一起。
另一种语言,如 Ruby 可能是比 C 更好的选择,它使您可以更多地关注数据,而不是数据在内存中的存储细节。一般来说,C 语言适合与操作系统进行快速、低级的交互,而具有垃圾编译器和动态类型的语言将更容易编写报告和聚合数据。
无论如何,假设您想使用 C。您选择的数据结构将取决于几件事。您正在建模的数据的精确真实世界结构是什么?您需要什么性能特征?添加东西需要快,还是从数据中提取某些统计数据需要快?在不知道这些问题的答案的情况下,我们很难为您的应用程序提供可用的答案。但乔纳森·莱弗勒 (Jonathan Leffler) 做出了很好的猜测。这是我的猜测:
#include <stdint.h>
struct student
{
char * name;
uint32_t sex;
uint32_t year_of_joining;
// Index into an array of sections.
// You could also use a pointer to a section (section *)
// but the pointer would become invalid if you ever moved the
// sections in memory (e.g. by calling realloc on an array
// of sections).
uint32_t section_id;
};
struct section
{
char * name;
uint32_t department_id;
};
struct department
{
char * name;
uint32_t college_id;
};
struct college
{
char * name;
uint32_t district_id;
};
struct district
{
char * name;
};
// These typedefs make it so we don't have to
// write "struct" when using the structs.
typedef struct student student;
typedef struct section section;
typedef struct department department;
typedef struct college college;
typedef struct district district;
// Dynamically sized arrays for holding things.
student * student_array;
section * section_array;
department * department_array;
college * college_array;
district * district_array;
我认为你在这里偏离了正轨。
请注意,单个 struct year_of_joining
大约是 100 MiB 的数据。一个包含 100 个这样的结构的数组需要大约 10 GiB 的数据(这只记录了学生的性别——根本没有其他信息)。
struct year_of_joining** year;
year = malloc(100 * sizeof(struct year_of_joining));
此内存分配为数百万个指针分配了足够 space。您几乎肯定打算使用:
struct year_of_joining *year = malloc(100 * sizeof(struct year_of_joining));
struct year_of_joining *year = malloc(100 * sizeof(*year));
这分配了 100 年的结构。
但是,您似乎不太可能有 13 个区,每个区正好有 153 个学院,每个学院正好有 17 个系,每个系有 8 个部门,每个部门正好有 100 名学生。这相当于每年超过 2500 万学生!
你将需要一个更加灵活的安排,其中每个结构都包含一个指向嵌套结构列表的指针,这样你就可以有更大的部门但更小的学院等。它需要更多的工作沿着:
struct students
{
char name[32];
int sex;
// ... and other data ...
};
struct sections
{
char name[32];
// ... and other data ...
int n_students;
struct students *students;
};
struct departments
{
char name[32];
int n_sections;
struct sections *sections;
}
struct colleges
{
char name[32];
// ... and other data ...
int n_departments;
struct departments *departments;
};
struct district
{
char name[32];
// ... and other data ..
int n_colleges;
struct college *colleges;
};
struct year_of_joining
{
int year;
// ... and other data ...
int n_districts;
struct district *districts;
};
即使这样感觉也不完全正确,但它会是一种比原来更好的组织数据的方式,如果只是因为如果一个部门只有一个部门并且只招收十名学生(因为它是少数群体利益department),那么它只分配足够的 space 给一个部门和 10 个学生,而不是分配 space 给 800 个学生和 8 个部门。
我有巨大的嵌套结构数组,这使得无法分配那种 space 并迫使我使用堆。但是我在使用 malloc
时遇到了困难。
问题的要点如下。
struct year_of_joining
{
struct district
{
struct colleges
{
struct departments
{
struct sections
{
struct students
{
int sex;
}student[100];
}section_no[8];
}department_no[17];
}college[153];
}dist[13];
};
如果我用
int main()
{
int i=0;
struct year_of_joining** year;
year = malloc(100 * sizeof(struct year_of_joining));
for (i = 0; i < 100; i++)
{
year[i] = malloc(sizeof(struct year_of_joining));
}
year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex = 1;//works fine
printf("%d", year[1]->dist[0].college[0].department_no[0].section_no[0].student[8].sex);//prints 1
free(year);
return 0;
}
它工作正常但是当我像 year_of_joining 创建一个指向 dist 的指针并使用间接运算符时它不编译:
year[1]->dist[2]->college[0].department_no[0].section_no[0].student[8].sex = 9;//error C2039: 'dist' : is not a member of 'year_of_joining'
我该如何解决这个问题?我走对了吗?
你的方向不对。您的结构非常庞大,如果输入的大小(例如学生人数)太大,您将需要重新编译程序。
我建议您将数据建模为可以单独分配的较小结构,也许使用指针或 ID 号将它们 link 在一起。
另一种语言,如 Ruby 可能是比 C 更好的选择,它使您可以更多地关注数据,而不是数据在内存中的存储细节。一般来说,C 语言适合与操作系统进行快速、低级的交互,而具有垃圾编译器和动态类型的语言将更容易编写报告和聚合数据。
无论如何,假设您想使用 C。您选择的数据结构将取决于几件事。您正在建模的数据的精确真实世界结构是什么?您需要什么性能特征?添加东西需要快,还是从数据中提取某些统计数据需要快?在不知道这些问题的答案的情况下,我们很难为您的应用程序提供可用的答案。但乔纳森·莱弗勒 (Jonathan Leffler) 做出了很好的猜测。这是我的猜测:
#include <stdint.h>
struct student
{
char * name;
uint32_t sex;
uint32_t year_of_joining;
// Index into an array of sections.
// You could also use a pointer to a section (section *)
// but the pointer would become invalid if you ever moved the
// sections in memory (e.g. by calling realloc on an array
// of sections).
uint32_t section_id;
};
struct section
{
char * name;
uint32_t department_id;
};
struct department
{
char * name;
uint32_t college_id;
};
struct college
{
char * name;
uint32_t district_id;
};
struct district
{
char * name;
};
// These typedefs make it so we don't have to
// write "struct" when using the structs.
typedef struct student student;
typedef struct section section;
typedef struct department department;
typedef struct college college;
typedef struct district district;
// Dynamically sized arrays for holding things.
student * student_array;
section * section_array;
department * department_array;
college * college_array;
district * district_array;
我认为你在这里偏离了正轨。
请注意,单个 struct year_of_joining
大约是 100 MiB 的数据。一个包含 100 个这样的结构的数组需要大约 10 GiB 的数据(这只记录了学生的性别——根本没有其他信息)。
struct year_of_joining** year;
year = malloc(100 * sizeof(struct year_of_joining));
此内存分配为数百万个指针分配了足够 space。您几乎肯定打算使用:
struct year_of_joining *year = malloc(100 * sizeof(struct year_of_joining));
struct year_of_joining *year = malloc(100 * sizeof(*year));
这分配了 100 年的结构。
但是,您似乎不太可能有 13 个区,每个区正好有 153 个学院,每个学院正好有 17 个系,每个系有 8 个部门,每个部门正好有 100 名学生。这相当于每年超过 2500 万学生!
你将需要一个更加灵活的安排,其中每个结构都包含一个指向嵌套结构列表的指针,这样你就可以有更大的部门但更小的学院等。它需要更多的工作沿着:
struct students
{
char name[32];
int sex;
// ... and other data ...
};
struct sections
{
char name[32];
// ... and other data ...
int n_students;
struct students *students;
};
struct departments
{
char name[32];
int n_sections;
struct sections *sections;
}
struct colleges
{
char name[32];
// ... and other data ...
int n_departments;
struct departments *departments;
};
struct district
{
char name[32];
// ... and other data ..
int n_colleges;
struct college *colleges;
};
struct year_of_joining
{
int year;
// ... and other data ...
int n_districts;
struct district *districts;
};
即使这样感觉也不完全正确,但它会是一种比原来更好的组织数据的方式,如果只是因为如果一个部门只有一个部门并且只招收十名学生(因为它是少数群体利益department),那么它只分配足够的 space 给一个部门和 10 个学生,而不是分配 space 给 800 个学生和 8 个部门。