我正在尝试编写一个带有链表数组的简单字典,但在调用显示函数后我不断丢失数据。
这是我的结构定义
typedef struct node{
int elem;
struct node *next;
}*L;
typedef L Dictionary[10];
这是我的显示
void display(Dictionary A)
{
int i;
for(i=0;i<10;i++){
printf("A[%d]: ",i);
while(A[i]!=NULL){
printf("%d\t",A[i]->elem);
A[i] = A[i]->next;
}
printf("\n");
}
}
解决这个问题的方法是创建一个临时变量。
我试过了
Dictionary tempStruct
for(i=0;i<10;i++){
tempStruct[i] = A[i];
}
并且它有效。但是还有其他比这种更有效的分配链表的方法吗?
tempStruct = A;
实际上不起作用,我得到 incomplete types node** to Dictionary{*node[10]}
最佳答案
您可以将显示函数中的循环更改为:
for(i=0;i<10;i++){
printf("A[%d]: ",i);
L tmp = A[i];
while(tmp!=NULL){
printf("%d\t",tmp->elem);
tmp = tmp->next;
}
printf("\n");
}
不需要复制整个数组,一个简单的临时指针在链表中导航就足够了。
旁注:对于数组的副本,您尝试使用tempStruct = A;
分配它。这不起作用的原因有两个:
在您的函数内,
A
没有数组类型。 C 不支持将数组传递给函数。当函数具有数组类型的参数时,它会自动调整为指针类型,并且不传递数组,而是传递指向数组第一个元素的指针。这种效果通常表示为数组作为指针而衰减,这就是您的消息不兼容类型节点**到字典{*node[10]}
的原因。即使
A
有数组类型,它仍然无法工作,因为 C 不允许分配给大批。这有点令人惊讶,因为同样的事情也适用于 struct 。我想不出为什么在 C 中不允许分配数组的充分理由,你应该记住你不能。当然,你可以手动完成,如果你不想分配每个元素,你可以使用函数memcpy()
,在string.h
中声明:int foo[5]; int bar[5] = {1, 2, 3, 4, 5}; // instead of foo = bar; memcpy(foo, bar, sizeof foo);
与您的问题无关,但我很难理解这段代码。你的 typedef 对于可读性来说是灾难性的。 永远将指针隐藏在typedef
后面——为了理解处理指针的代码,指针明显很重要。数组类型的 typedef 至少也是有问题的。我建议使用以下代码:
typedef struct node {
int elem;
struct node *next;
} node;
// not strictly necessary, but IMHO, if you want to typedef a struct type,
// it's the least confusing option to name it the same as the struct tag.
#define DICTSIZE 10
void display(node **a) // variable names are often lowercase by convention
{
// to cope with ANY possible size, you need size_t, int might be too small
// include stddef.h or stdlib.h to use it. Of course, with 10 elements,
// int is enough.
for (size_t i = 0; i < DICTSIZE; ++i) {
printf("a[%zu]: ", i);
node *tmp = a[i];
// now it's obvious tmp is a pointer, so no need to explicitly
// write the != NULL ... (any pointer that's not NULL evaluates true)
while (tmp) {
printf("%d\t", tmp->elem);
tmp = tmp->next;
}
printf("\n");
}
}
还要注意一些添加的空格如何极大地提高代码的可读性(因此,使用它们)。
我认为您原来的显示功能已损坏,因为它修改了显示的内容。对于显示数据的函数来说,这不是预期的行为。如果您想进一步改进您的代码,您应该使用 const 来明确该函数不应修改它接收到的内容,以便编译器可以捕获错误。在上面的示例中,display
的签名最好如下所示:
void display(const node *const *a)
第一个 const
将使任何 struct 节点
不可变,第二个 const
(星号之后)使数组中的指针不可变。有了这个,你还必须写
const node *tmp = a[i];
因为你不能将 const 指针分配给非常量指针。
关于C 数组链表,将一个数组链表分配给另一个数组链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45654764/