C 数组链表,将一个数组链表分配给另一个数组链表

标签 c arrays linked-list variable-assignment

我正在尝试编写一个带有链表数组的简单字典,但在调用显示函数后我不断丢失数据。

这是我的结构定义

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/

相关文章:

arrays - 通过 [String][String] 进行嵌套数组/对象访问

Java - 检查数组是否包含 3 个连续日期

c - 为什么需要转换从函数返回的结构?

c - strtok() 函数自动忽略不是我的分隔符的数据

c++ - 从 OpenSSL 中的私钥中提取公钥

c - 如何找出在C中存储一个值(int)需要多少字节

Java - ArrayList<Integer> 作为参数...?

c++ - 如何创建一个函数,仅通过更改链接来交换单向链表中的两个相邻元素?

c++ 对象 vector ,包含动态分配的内存 - 'erase' 不起作用

java - LinkedList 无法复制某些重复的数字