双链表出错,我找不到'*'之前缺少的属性
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){ ... }
您在此处将 int
与 NULL
进行比较:
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)
比较 int
和 NULL
;您可能希望 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;
}
这里是 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){ ... }
您在此处将 int
与 NULL
进行比较:
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)
比较int
和NULL
;您可能希望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;
}