c语言 - 双链表错误,我找不到"*"之前缺少的属性



C 初学者在这里,试图了解更多关于链表的信息。

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

所以当用户输入n=6时,链表将如下所示:

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

我被困在这里已经有一段时间了。我试图看到我错过了什么,但看不到它。一切都编译文件,除了我只收到以下错误:[错误] 在"*"标记之前预期"="、"、";"、"asm"或"__attribute__">

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

有一些错误。返回类型不正确,数据初始化会发出警告,因为您正在比较指针和整数,但最重要的错误是您没有为 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;
}

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


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。如果不这样做,最终会出现内存泄漏。对于一个小程序来说可能无关紧要,但尽早学习是一个好习惯。

看起来你正在解决约瑟夫斯问题!

这里有各种编译问题需要首先解决。使用类似标志编译代码

-Wall -Wextra -Werror -O2 -std=c99 -pedantic

如果你还没有。编码时,请经常编译和运行。使用 valgrind 等工具来验证您的代码不会泄漏内存并帮助检测分段错误。


编译器问题:

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

最新更新