双链表错误,我在'*'

时间:2019-10-24 14:49:40

标签: c compiler-errors doubly-linked-list circular-dependency

这里是C的初学者,试图了解有关链接列表的更多信息。

下面的代码应该从称为“士兵”的结构创建一个循环的双向链表。 int n很重要,因为它确定了创建的节点数,每个节点都包含一个int data,且值为n的{​​{1}}。

因此,当用户输入n=>1时,链接列表将如下所示:

n=6

我已经在这里停留了一段时间。我正在尝试查看丢失的内容,但看不到。一切都会编译文件,除了我只会得到以下错误: [Error]预期在'*'标记之前的'=',',',';','asm'或'__attribute __'

6 <-> 5 <-> 4 <-> 3 <-> 2 <-> 1
^                             ^
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|

3 个答案:

答案 0 :(得分:1)

我发现了一些潜在的问题:


您的create_soldier原型具有两种返回类型:

void soldier* create_soldier (int sequence){ ... }

您必须选择一个!我在函数中没有看到return,因此它可能应该是目前的void函数:

void create_soldier (int sequence){ ... }


您正在此处比较intNULL

if(head->data==NULL)

NULL只能与指针进行有意义的比较,因此您可能打算比较指向士兵head而不是其data成员的指针:

if (head == NULL)


void display(soldier* head)被定义了两次,因此您需要删除或重命名一个定义。它们看起来与我相同,所以我认为您可以删除一个。


最后,别忘了free用完malloc后分配给您的内存。如果不这样做,最终将导致内存泄漏。对于一个小的程序来说可能并不重要,但是这是一个提早开始的好习惯。

答案 1 :(得分:1)

有一些错误。返回类型不正确,数据初始化会发出警告,因为您正在将指针与int进行比较,但是最重要的错误是您没有为head分配内存,并且没有正确地初始化'head'。另外,完成后应该释放内存(我没有放入)。我也没有检查代码是否完全符合您的要求,但是可以运行以下代码:

#include<stdio.h>
#include<stdlib.h>

typedef struct nod {
    int                data;
    struct nod *prev, *next;
} soldier;

soldier *head;

void create_soldier (int sequence) {
    if(head->data == 0) {    // when the linked list starts
        head->data = sequence;
        head->prev = NULL;
        head->next = NULL;
    }

    else{
        soldier *temp;
        soldier *t;
        temp= (soldier *) malloc(sizeof(soldier));
        temp->data = sequence;
        temp->next = NULL;

        t = head;    //Traversing
        while (t->next != NULL)
            t = t->next;

        if(temp->data==1){      //for the rear end of the array to link back to the head
            t->next = temp;
            temp->prev = t;
            temp->next = head;
            head->prev = temp;
        }
        else{
            t->next = temp;
            temp->prev = t;
        }
    }
}

void display(soldier* head){
    soldier *t;
    t=head;

    while (t->next != head){
            printf("%d", t->data);
            t= t->next;
    }
}

int main()
{
    int n, k;
    printf("Enter the number of soldiers to be executed");
    scanf("%d", &n);
    printf("Enter the number of soldiers to be skipped");
    scanf("%d", &k);

    head = (soldier *) malloc(sizeof(soldier));
    for ( ; n>= 1; n--)
        create_soldier(n);

    display(head);

    free(head);
    return 0;
}

答案 2 :(得分:1)

好像您正在解决Josephus Problem

这里首先要解决各种编译问题。使用类似

的标志来编译代码
-Wall -Wextra -Werror -O2 -std=c99 -pedantic

(如果尚未)。在编写代码时,请经常编译并运行。使用valgrind之类的工具来验证您的代码是否不是leak memory并帮助检测segmentation faults


编译器问题:

  • void soldier* create_soldier (int sequence)是无效的函数,因为它指定了两种返回类型。它应该为void create_soldier(int sequence),因为它不会返回任何内容。
  • display被定义了两次。
  • 警告:if(head->data==NULL)比较intNULL;您可能希望0是有效的data值,而意图可能是if (head == NULL)

运行时问题:

  • (head->data==NULL)create_solder函数开始,但这会立即取消引用空指针。
  • 已分配但未释放内存。

设计问题和样式建议:

  • 不需要全局变量head。它应该在main范围内,并传递给需要它的任何函数。
  • 与上一点保持一致,这些函数不可重用,因为它们的实现完全绑定到全局变量head,例如,无法创建多个列表。尝试编写不会改变外部状态的pure functions。这样一来,程序就更不会出错,并且更易于推理。
  • 与上一点保持一致,您最好在代码中使用node之类的通用名称,而不要使用soldier。我们希望能够编写一个双向链接列表“类”,并将其重用于任何目的(例如解决此特定问题)。如果需要,只需添加现有typedef soldier类型的node别名即可。
  • void create_soldier (int sequence)并不是一个非常有用的功能,因为我们很少需要使用来自1..n的数据来创建列表。更常见的是,我们只想创建一个node并为其提供一些任意数据。考虑到这一点,我希望使用void create_node(node **head, int data),它只会创建一个node。然后,我们可以在main中运行循环,以根据问题规范创建n节点(或为运行create_node逻辑的1..n编写包装函数)。
  • for循环优先于while循环。它们更加干净,并且使变量的作用域范围小而紧凑。
  • 无需cast the result of malloc

这是一个重写建议:

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
    int data;
    struct node *prev, *next;
} node;

void create_node(node **head, int data) {
    if (*head) {
        node *new_node = malloc(sizeof(*new_node));
        new_node->data = data;
        new_node->next = *head;
        new_node->prev = (*head)->prev;
        (*head)->prev->next = new_node;
        (*head)->prev = new_node;
    }
    else {
        *head = malloc(sizeof(**head));
        (*head)->data = data;
        (*head)->prev = *head;
        (*head)->next = *head;
    }
}

void display(node *head) {
    node *t = head;

    if (t) {
        printf("%d->", t->data);

        for (t = t->next; t != head; t = t->next) {
            printf("%d->", t->data);
        }

        puts("");
    }
}

void free_list(node *head) {
    node *t = head;

    if (t) {
        for (t = t->next; t != head;) {
            node *dead_node = t;
            t = t->next;
            free(dead_node);
        }

        free(head);
    }
}

int main() {    
    int n;
    node *head = NULL;
    printf("Enter the number of soldiers to be executed: ");
    scanf("%d", &n);        

    for (int i = 0; i < n; create_node(&head, ++i));

    display(head);
    free_list(head);
    return 0;
}