我必須創建一個結構書的鏈表,我的問題是當我創建一個新節點并在其中輸入一本新書的屬性時,我以前節點中所有以前的書都將它們的名稱更改為我輸入的最后一本,雖然出版年份仍然是原始的。有人可以解釋這是如何作業的,以及我必須做些什么才能使其正常作業?
這是我的代碼
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define N 255
struct Book {
char *title;
int year;
};
struct Node {
struct Book book;
struct Node *next;
};
struct Book createBook(char *title, int year) {
struct Book book = {title, year};
return book;
}
void print(struct Node *head) {
struct Node *curr_node = head;
while (curr_node != NULL) {
printf("%s(%d)\n", curr_node->book.title, curr_node->book.year);
curr_node = curr_node->next;
}
}
void add(struct Node **head, struct Book book) {
struct Node *new_node;
struct Book *new_book;
new_node = (struct Node*) malloc(sizeof( struct Node ));
new_book = &new_node->book;
new_book->title = book.title;
new_book->year = book.year;
new_node->next = (*head);
*head = new_node;
}
void pop(struct Node **head) {
struct Node *next_node = NULL;
if (*head == NULL) {
printf("List is empty!");
return;
}
next_node = (*head)->next;
free(*head);
*head = next_node;
}
void reverse(struct Node **head) {
struct Node *prev_node = NULL;
struct Node *curr_node = *head;
struct Node *next_node = NULL;
while (curr_node != NULL) {
next_node = curr_node->next;
curr_node->next = prev_node;
prev_node = curr_node;
curr_node = next_node;
}
*head = prev_node;
}
void clear(struct Node **head) {
struct Node *curr_node = *head;
struct Node *temp_node = NULL;
while (curr_node != NULL) {
temp_node = curr_node->next;
free(curr_node);
curr_node = temp_node;
}
*head = NULL;
}
int main() {
struct Node *head = NULL;
short process = 1; // 1 for True 0 for False
int option = 0;
char title[N];
int year = 0;
while (process) {
printf("List of actions:\n");
printf("1:\tAdd element\n");
printf("2:\tRemove element\n");
printf("3:\tReverse list\n");
printf("4:\tPrint list\n");
printf("5:\tClear list\n");
printf("0:\tExit\n");
scanf("%d", &option);
switch (option) {
case 1:
printf("Enter book\'s title: ");
scanf("%s", title);
printf("Enter book\'s year of publishing: ");
scanf("%d", &year);
add(&head, createBook(title, year));
printf("\n");
break;
case 2:
pop(&head);
break;
case 3:
reverse(&head);
break;
case 4:
print(head);
break;
case 5:
clear(&head);
break;
case 0:
process = 0;
break;
default:
printf("\n");
printf("**************************\n");
printf("Enter numbers from 1 to 5!\n");
printf("**************************\n");
printf("\n");
continue;
}
}
return 0;
}
uj5u.com熱心網友回復:
你總是傳遞一個指向title在 main 中宣告的同一個本地陣列的指標
char title[N];
到函式 createBook
add(&head, createBook(title, year));
所以title所有節點的資料成員
struct Book {
char *title;
int year;
};
由于函式內的此初始化,指向title在 in 中宣告的相同本地陣列main
struct Book book = {title, year};
即title在main用作函式的引數運算式中宣告的區域陣列createBook被隱式轉換為指向其第一個元素的指標。并且所有函式呼叫都處理陣列第一個元素的相同地址。
您需要title為每個節點動態分配參考陣列的副本。
另一種方法是title將結構的資料成員宣告Book為具有字符陣列型別而不是指標型別。
uj5u.com熱心網友回復:
謝謝,現在一切正常!
在 switch 陳述句之前,我在主函式的 while 回圈中為我的字符指標分配了記憶體:
char *title = (char *) calloc(N, sizeof(char));
所以現在作業代碼如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define N 255
struct Book {
char *title;
int year;
};
struct Node {
struct Book book;
struct Node *next;
};
struct Book createBook(char *title, int year) {
struct Book book = {title, year};
return book;
}
void print(struct Node *head) {
struct Node *curr_node = head;
while (curr_node != NULL) {
printf("%s(%d)\n", curr_node->book.title, curr_node->book.year);
curr_node = curr_node->next;
}
}
void add(struct Node **head, struct Book book) {
struct Node *new_node;
struct Book *new_book;
new_node = (struct Node*) malloc(sizeof( struct Node ));
new_book = &new_node->book;
new_book->title = book.title;
new_book->year = book.year;
new_node->next = (*head);
*head = new_node;
}
void pop(struct Node **head) {
struct Node *next_node = NULL;
if (*head == NULL) {
printf("List is empty!");
return;
}
next_node = (*head)->next;
free(*head);
*head = next_node;
}
void reverse(struct Node **head) {
struct Node *prev_node = NULL;
struct Node *curr_node = *head;
struct Node *next_node = NULL;
while (curr_node != NULL) {
next_node = curr_node->next;
curr_node->next = prev_node;
prev_node = curr_node;
curr_node = next_node;
}
*head = prev_node;
}
void clear(struct Node **head) {
struct Node *curr_node = *head;
struct Node *temp_node = NULL;
while (curr_node != NULL) {
temp_node = curr_node->next;
free(curr_node);
curr_node = temp_node;
}
*head = NULL;
}
int main() {
struct Node *head = NULL;
short process = 1; // 1 for True 0 for False
int option = 0;
int year = 0;
while (process) {
printf("List of actions:\n");
printf("1:\tAdd element\n");
printf("2:\tRemove element\n");
printf("3:\tReverse list\n");
printf("4:\tPrint list\n");
printf("5:\tClear list\n");
printf("0:\tExit\n");
scanf("%d", &option);
char *title = (char *) calloc(N, sizeof(char));
switch (option) {
case 1:
printf("Enter book\'s title: ");
scanf("%s", title);
printf("Enter book\'s year of publishing: ");
scanf("%d", &year);
add(&head, createBook(title, year));
printf("\n");
break;
case 2:
pop(&head);
break;
case 3:
reverse(&head);
break;
case 4:
print(head);
break;
case 5:
clear(&head);
break;
case 0:
process = 0;
break;
default:
printf("\n");
printf("**************************\n");
printf("Enter numbers from 1 to 5!\n");
printf("**************************\n");
printf("\n");
continue;
}
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/394537.html
