很抱歉提出一个基本问题,我正在学习C而且我对为列表分配值感到困惑。我对自己的问题感到困惑,这个问题突然出现在我脑海里...... :(
例如,我有一个结构
typedef struct {
int value_in_use;
} structA;
typedef struct structB {
structA conn;
struct structB *next, *prev;
} structB
typedef struct {
structB *head, *tail;
} structC;
我希望将“value_in_use”的值指定为1.我完全感到困惑,正如我所理解的那样,在列表中,我需要首先从头部遍历(StructC),我需要进入内部列表直到我进入structA并为其赋值。像
这样的东西 structC *C = NULL;
C = (structC *) malloc(sizeof(structC));
int assign=1;
&C->structB.head->conn.value_in_use=assign;
与此同时,我认为我实际上可以直接为structA指定一个指针并为其赋值。所以我可以说
structA *ue = NULL;
ue = (structA *) malloc(sizeof(structA));
ue->value_in_use = 100;
在第一部分和第二部分中如何在运行时分配列表的值有何不同?我相信我可以同时使用它们来分配值(或?)..
非常感谢您与我分享您的知识。
答案 0 :(得分:3)
事实上,第一个实际上并不起作用。你试图跟随C的头指针,但你不知道指针指向哪里(即malloc不是递归的)。
对于第一种情况,您需要执行以下操作:
structC * c = malloc(sizeof(structC));
structB * b = malloc(sizeof(structB));
c->head = b;
c->tail = b;
b->next = NULL;
b->prev = NULL;
c->head->conn.value_in_use = 1;
请注意,我们不必单独分配structA,因为B中嵌入了一个。
答案 1 :(得分:1)
您必须首先为structC
分配内存,然后您必须为其中的指针(*head
,*tail
)分配内存,然后您可以为{{1}分配值}}
以下是3步骤的详细说明及解释:
第1步:
conn
structC *C = NULL;
C = (structC *) malloc(sizeof(structC));
现在只是指向C
类型的指针,这意味着它只指向堆栈上某处指针类型大小的内存。通过使用struct C
,您正在为此分配(保留)大小为malloc
的空间。
第2步:
struct C
现在结构 C->head= (structA *) malloc(sizeof(structA));
内的指针head
再次指向一个指针大小的内存,你需要使用malloc为它分配一个大小(C(structC)
)上面的陈述。
第3步:
一旦structA
指向足以容纳C->head
的内存,您现在就可以为其分配您选择的值。
strct A
答案 2 :(得分:0)
我不确定从哪里开始。请注意,structA
,structB
和structC
似乎代表了您的双向链接列表实现的不同“级别”。 structA
表示实际数据或列表成员,structB
表示数据成员及其连接,structC
表示整个列表本身。另请注意,structC
仅包含指针到列表中的值。通过在第一个代码示例中分配structC
,它将不包含任何有用信息或为成员分配空间。您应该立即清除内存,因为指针无效。因此,您的第一个代码示例将无法正常工作。我希望你会做类似的事情(警告:未经测试的代码)
structC* c = malloc(sizeof(structC)); // note: don't cast the pointer from malloc in C
structB* b = malloc(sizeof(structB)); // you now have a data member
memset(b, 0, sizeof(structB));
c->head = b;
c->tail = b;
b->conn.value_in_use = 1;
现在您有一个列表,其中包含一名成员。
答案 3 :(得分:0)
你在第二个例子中写入随机存储器,adress-of运算符(&
)是罪魁祸首(我很惊讶C编译器没有捕获到错误)。
在第三个示例中,您只需为structA
分配内存,ua
指向的内容与任何类似于树结构的内容都没有关联。正如您已实施structB
一样,conn
的内存是记录的一部分,如果structB
的内存是malloc
动态分配的,那么您获得conn
免费作为分配内存的一部分。如果在静态内存或堆栈中创建structB
作为“正常”(从不使用指针或动态内存分配的语言的角度来看)变量,那么记录conn
分享同样的记忆。
我希望我没有加入混乱(抱歉我缺乏英语技能)
我可以给你一些好的建议:
首先:我建议您使用更具描述性的名称作为开头。为什么不对结构root
,node
和data
。
第二:我推荐阅读一本关于C.的优秀初学者书.Cernighan&amp ;; Ritchie是一个经典之作,但是对指针的处理不多,对于没有任何事先接触过其他编程语言的人来说它很容易阅读,但实际上并不是一本开始编程的书。 Kenneth Reek在C上的指针集中在与其他编程语言不同的C部分,主要是指针和C内存模型。 C上的指针还提供了基本数据结构的良好实现,如树。据我所知,对于有抱负的C程序员来说,互联网上没有任何好文章。
第三:阅读有关数据结构和与其一起使用的算法的好书或网页。我已经看过一些关于这个主题的好网页,但我现在无法找到它们。