我正在练习写一个链表,它将从用户那里按升序获取数字,并告诉您使用的唯一数字是什么。在它索引我的findUnique函数和我的while循环之后,我一直得到一个分割错误,我已经设置了在它进入不打印任何东西之前打印列表。这只是链表的练习,所以任何帮助都会很感激。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct number{
int num;
struct number* next;
}Number;
Number *addterm(Number*, int);
void findUnique(Number*);
int main(void){
Number *Number_List = NULL;
int digit = 1;
printf("Enter numbers in ascending order(enter 0 to stop): ");
scanf("%d", &digit);
while(digit != 0){
addterm(Number_List, digit);
printf("Enter numbers in ascending order(enter 0 to stop): ");
scanf("%d", &digit);
}
printf("ntest 1n");
Number *ptr = Number_List;
while(ptr){
printf("%d ", ptr -> num);
Number_List = ptr -> next;
}
printf("ntest 2n");
printf("n");
findUnique(Number_List);
return 0;
}
Number *addterm(Number* list, int userIn){
Number *newNum = (Number *) malloc ( sizeof (Number) );
newNum->num = userIn;
newNum->next = list;
if(list == NULL){
return newNum;
}
Number *ptr = list;
while( ptr->next != NULL ){
ptr = ptr->next;
}
ptr->next = newNum;
return list;
}
void findUnique(Number* list){
int print, temp;
print = list->num;
temp = print;
printf("The unique numbers you entered are %d", temp);
while( list ){
print = list->num;
if(print == temp){
continue;
}
else{
temp = print;
printf(" %d", temp);
}
list = list -> next;
}
return;
}
错误1:
addterm(Number_List, digit);
应为
Number_List = addterm(Number_List, digit);
你忘记更新列表指针了
错误2:while(ptr){
printf("%d ", ptr -> num);
Number_List = ptr -> next;
}
应为
while(ptr){
printf("%d ", ptr -> num);
ptr = ptr -> next;
}
这会产生一个无限循环。
错误3:newNum->next = list; //In addTerm()
应为
newNum->next = NULL;
新节点没有下一个节点集。这也产生了一个无限循环。
错误4:if(print == temp){
continue;
}
应为
if(print == temp){
list = list->next;
continue;
}
另一个无限循环
我尝试过这个问题,我认为错误是在您的findUnique
函数中。下面的@MatzZze已经涵盖了这些问题,它将帮助修复您当前的代码。
或者,您可以尝试这种方法。它展示了从链表中删除重复项的另一种方法,并适当地更新链表。我所包含的额外代码只是为了帮助运行程序。
在这里:
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node node_t;
struct node {
data_t num;
node_t *next;
};
typedef struct {
node_t *head;
node_t *foot;
}list_t;
list_t *make_empty_list(void);
list_t *add_term(list_t *list, data_t value);
void read_terms(list_t *list);
void print_unique_terms(list_t *list);
list_t *unique_terms(list_t *list);
void print_list(list_t *list);
void free_list(list_t *list);
int
main(int argc, char const *argv[]) {
list_t *list;
list = make_empty_list();
read_terms(list);
printf("Your numbers are:n");
print_list(list);
unique_terms(list);
printf("The unique numbers you entered are:n");
print_list(list);
free(list);
return 0;
}
void
read_terms(list_t *list) {
int digit;
printf("Enter numbers in ascending order(enter 0 to stop): ");
while (scanf("%d", &digit) == 1) {
if (digit == 0) {
break;
} else {
add_term(list, digit);
}
}
}
list_t
*add_term(list_t *list, data_t value) {
node_t *node;
node = malloc((sizeof(*node)));
node->num = value;
node->next = NULL;
if (list->foot == NULL) {
list->head = list->foot = node;
} else {
list->foot->next = node;
list->foot = node;
}
return list;
}
list_t
*unique_terms(list_t *list) {
node_t *node = list->head;
while (node != NULL && node->next != NULL) {
if (node->num == node->next->num) {
node->next = node->next->next;
} else {
node = node->next;
}
}
return list;
}
void
free_list(list_t *list) {
node_t *curr, *prev;
curr = list->head;
while (curr) {
prev = curr;
curr = curr->next;
free(prev);
}
free(list);
}
void
print_list(list_t *list) {
node_t *node = list->head;
while (node != NULL) {
printf("%d ", node->num);
node = node->next;
}
printf("n");
}
list_t
*make_empty_list(void) {
list_t *list;
list = malloc(sizeof(*list));
list->head = NULL;
list->foot = NULL;
return list;
}
这些都是很棒的答案,它们肯定会帮助您完成这段代码。
然而,我建议如下:这个问题的真正答案是,这是一个链表,你可能知道:
+------+ +------+ +------+
| data | | data | | data |
+------+ +------+ +------+
| next |---->| next |---->| next |----> NULL
+------+ +------+ +------+
^
|
START (Keep track of the whole list.)
你可能遇到的最大危险是你的next和start指针。现在来回答你的问题,用一种能帮助你做以下事情的方式:
在IDE中启用调试,并在程序入口点设置断点。在快速射击中使用Step over工具,直到程序出错。现在你知道是哪一行引起的了。
在该行上放置一个断点,并调试到该点,并确定何时设置导致问题的指针。
许多IDE提供了一个工具,可以在变量上放置一个"监视",只有当您指定的变量等于您指定的值时,才会在某个点中断程序,在这种情况下,我建议为NULL。
因为现在你得到分段错误,你需要看看你有循环的地方,因为你可能迭代超过你的列表的界限。
学习调试技术才是解决这个问题的正确方法!
祝你好运!