双链表出错,我找不到'*'之前缺少的属性

Error with Double Linked List, I can't find the missing attribute before '*'

这里是 C 初学者,正在尝试了解有关链表的更多信息。

下面的代码应该从名为 "soldier" 的结构创建一个循环双向链表。 int n很重要,因为它决定了创建的节点数,每个节点包含一个int data,值为n,只要n=>1.

所以当用户输入n=6时,链表会是这样的:

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

我已经被困在这里一段时间了。我想看看我错过了什么但看不到它。一切都编译文件,除了我只得到以下错误: [Error] expected '=', ',', ';', 'asm' or '__attribute__' before '* '令牌

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

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

soldier *head;

void soldier* create_soldier (int sequence){
    if(head->data==NULL)    //when the linked list starts
        head->data = sequence;

    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;
    }   
}

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);

    for ( ; n>= 1; n--)
        create_soldier(n);

    display(head);

    return 0;
}

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


create_soldier 的原型有两种 return 类型:

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 分配的内存。如果你不这样做,你最终会发生内存泄漏。对于一个小程序来说可能无所谓,但早点开始是个好习惯。

有一些错误。 return 类型不正确,数据初始化给出警告,因为你正在比较指针和 ints,但最重要的错误是你没有分配内存到 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;
}

看来您正在解决 Josephus Problem!

这里有很多编译问题需要首先解决。使用

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

如果你还没有。在编写代码时,经常编译和 运行。使用像 valgrind to verify that your code doesn't leak memory and help detect segmentation faults.

这样的工具

编译器问题:

  • void soldier* create_soldier (int sequence) 是无效函数,因为它指定了两个 return 类型。它应该是 void create_soldier(int sequence) 因为它没有 return 任何东西。
  • display 定义了两次。
  • 警告:if(head->data==NULL) 比较 intNULL;您可能希望 0 成为一个有效的 data 值,其意图可能是 if (head == NULL).

运行时问题:

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

设计问题和风格建议:

  • 不需要全局变量head。它应该在 main 范围内并传递给任何需要它的函数。
  • 与前一点一致,这些函数不可重用,因为它们的实现完全绑定到全局变量 head,例如,无法创建多个列表。尝试编写不改变外部状态的 pure functions。这使得程序更不容易出错并且更容易推理。
  • 与上一点保持一致,更喜欢为您的代码使用 node 之类的通用名称,而不是 soldier。我们希望能够编写一个双向链表 "class" 并将其重复用于任何目的(例如解决这个特定问题)。如果你想要这个,只需添加现有 node 类型的 typedef soldier 别名。
  • void create_soldier (int sequence) 不是一个非常有用的函数,因为我们很少需要使用来自 1..n 的数据创建列表。更常见的是,我们只想创建一个 node 并给它一些任意数据。考虑到这一点,我更喜欢 void create_node(node **head, int data),它只创建一个 node。然后我们可以 运行 main 中的一个循环来根据问题规范创建 n 个节点(或者为 create_node 编写一个包装函数 运行 是 1..n逻辑)。
  • while 循环更喜欢 for 循环。它们更简洁,并且使变量的范围更小。
  • 不需要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;
}