如何构建和管理这个复杂的C数据结构?
我很困惑如何在 C 中有效地管理(填充和访问)以下数据结构。简单描述一下,我有一个包含另一个结构的成员的结构,并且该结构有另一个不同结构的成员,所以四。像这样的:
typedef struct
{
int num;
} D;
typedef struct
{
D *boo;
} C;
typedef struct
{
C *far;
} B;
typedef struct
{
int foo;
B *bar;
} A;
A *func() {
A *var;
// POPULATE var
}
int main(...) {
A *a = func();
// PRINTING
}
那么,哪种方式是管理这个数据结构的最佳方式呢?我的意思是如何填充这个 A 类型指针的数据?
想象一下,我要打印 a
保留的所有数据(在 // PRINTING
处),我想我会得到如下内容: a- >bar->far->boo->num
。我不知道这是否正常工作,因此是否可靠。
I'm quite confusing how to efficiently manage (populating and accessing) the following data structure in C. To describe in brief, I have a struct that contains a member of another struct, and that struct has a member of another different struct and so forth. Something like this:
typedef struct
{
int num;
} D;
typedef struct
{
D *boo;
} C;
typedef struct
{
C *far;
} B;
typedef struct
{
int foo;
B *bar;
} A;
A *func() {
A *var;
// POPULATE var
}
int main(...) {
A *a = func();
// PRINTING
}
So, which way is the best way to manage this data structure? I mean how am I going to populate the data for this A-typed pointer?
Imagine that I'm about to print all the data that a
keeps (at // PRINTING
), I guess I'm gonna have something like: a->bar->far->boo->num
. I don't know whether this properly works and thus, is robust.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这在例如Python中不会更容易,如果你选择这样一个分散的设计,那么管理起来自然会有点痛苦。
打印就像你说的那样工作,C 的
->
运算符通常就是这样使用的。当然,如果结构不“完整”,可能存在 NULL 指针,则需要在取消引用指针之前检查这一点,否则将出现未定义的行为。填充可能最好通过编写函数在每一层创建一个实例来完成,然后可以在链中相互调用以设置最顶层的类型:
这有点麻烦,因为所有实际数据(
foo
和num
)必须传递到创建A
实例的顶级函数,但它可以工作并且非常简单。请注意,我们如何通过确保
B
指针为非NULL
来捕获来自较低级别内存分配器的错误。这些类型的检查在其他create
函数中也是必要的。This wouldn't be any easier in e.g. Python, if you're selecting such a scattered design then it's going to be a bit painful to manage, naturally.
The printing would work just as you say, C's
->
operator is typically used just like that. Of course, if there can be NULL pointers where the structure is not "complete" you need to check for that before dereferencing the pointer, or you will have undefined behavior.Population would probably be best done by writing functions to create an instance at each layer, which can then call each other in a chain to set up the top-most type:
This is a bit cumbersome since all the actual data (
foo
andnum
) must be passed in to the top-level function that creates an instance ofA
, but it works and is very straight-forward.Notice how we catch errors from the lower-level memory allocators, by making sure the
B
pointer is non-NULL
. These kinds of checks would be necessary in the othercreate
-functions, too.如果不知道为什么选择使用指针,就不可能回答“我如何管理这个”。如果每个
A
拥有自己的B
等等,那么在分配A
的时候就需要分配B
>,并在释放A
时释放它。但在这种情况下,指针就没用了,而且会产生额外的工作。您可以这样做:如果指针的原因是您可能有多个
A
实例,它们都指向B
的同一个实例,那么您需要决定您如何知道B
的实例何时不再使用并且可以被释放。有一些通用的解决方案,例如引用计数,或者可能有一些特定于您的应用程序的解决方案可以使问题的答案变得容易。It's not possible to answer "how do I manage this", without knowing why you've chosen to use pointers. If each
A
owns its ownB
and so on, then you need to allocate theB
when you allocate theA
, and free it when you free theA
. But in that case the pointer is useless and creates extra work. You could just have done:If the reason for the pointer is that you could have several instances of
A
that all point to the same instance ofB
, then you need to decide how you will know when that instance ofB
is no longer in use and can be freed. There are some general-purpose solutions like reference counting, or there might be something specific to your application that makes the answer to the question easy.