我花了最后2.5个小时来创建这个链表并尝试理解为什么它没有将内存地址传递给列表的头部。我正在尝试理解C中的链表,然后再转到我的类学习java中的数据结构。我查看了其他问题,但我不明白为什么它不起作用。请原谅我一直在努力理解一切的评论。在此先感谢您的时间和帮助!
新赋值后head变量等于NULL head = addFamMember(NULL);在主线程中。但是我可以看到通过打印它的成员(名称,年龄和下一个指针)已经在add函数内部分配了内存。这是输出:
Enter command to add, print, or quit: add
Enter name and age: brett 28
Added:brett Age:28 POINTING to:(null)
Enter command to add, print, or quit:
这是代码:我留下了他的评论,可能有助于描述我的想法并找出我出错的地方。
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct S_Family{
char name[16];
int age;
struct S_Family *next;
}Family;
//prototypes
Family *addFamMember (Family *previous);
void CleanUp(Family *start);
void PrintList(Family *start);
int main(){
setvbuf(stdout, NULL, _IONBF, 0);
printf("Enter command to add, print, or quit: ");
char input[16]; //fgets var to store input
char command[16]; //sscanf var to store read info from input
Family *head = NULL; //For a linked list we need to set up the first node and point it NULL
Family *newest = NULL; //We also need a pointer dedicated to updating the latest created node
//This while loop will continue to get input until the command "quit" is typed
//It includes the functionality of printing the list and adding new nodes
while( fgets(input, 15, stdin)){
sscanf(input, "%s", command);
if ( strcmp(command, "quit") == 0) {
printf("\n\nBreaking.........");
break;
} else if ( strcmp(command, "print") == 0) {
PrintList(head);
} else if ( strcmp(command, "add") == 0) {
if ( head = NULL){
head = addFamMember(NULL); //If there are no nodes give head a memory address so now we do (recursion somewhat?)
printf("head:%s ", head->name); //this doesn't print!! Head = NULL above for some reason.
newest = head; //newest cannot stay equal to NULL. this allows us to pass it as a param to add function w/out the start being NULL anymore
printf("newest:%s ", newest->name);
} else {
newest = addFamMember(newest); //Recursion where the new node gets a mem address and gets the previous node as guide to cont. the list
} //now we go to the add function
}
printf("\nEnter command to add, print, or quit: ");
}
CleanUp(head);
return 0;
}
/*We want to return a new family member structure
so we start of with a Family return type. The param
as mentioned before needs to be a pointer to the address
of the previous node. That node will be pushed away from the
NULL in a singly or doubly linked list */
Family *addFamMember (Family *previous) {
/*Now we need to get the member variable info for that newFamMember
and store into the newly created data structure newFamMember*/
char input[16];
printf("Enter name and age: ");
fgets(input,15, stdin);
Family *newFamMember = malloc(sizeof(Family)); //create new address for newFamMember
sscanf(input, "%s %d", newFamMember->name, &newFamMember->age); //takes the input (first a string then a integer) and stores it into its proper place
printf("Added:%s Age:%d POINTING to:%S \n\n",newFamMember->name,newFamMember->age, newFamMember->next->name);
newFamMember->next = NULL; //initialize it's pointer member var but more importantly maintains the linked list by pointing to null.
/*Now we tell the computer what to do if this isn't the first node
or not. If it is then there isn't a previous node so there is no
way to set any other nodes' pointers to point to something else*/
if ( previous != NULL){
previous->next = newFamMember; //if previous is not equal to NULL set the previous' next pointer to newFamMember
printf("previous:%s ", previous->next->name);
}
return newFamMember; //we always want to return a newly added family member. That's this function's purpose
}
/*now we can print the list*/
void PrintList (Family *head) { //start is a pointer so we can pass the value of start
Family *currentMember = head; //we create currentMember and set it equal to start so we can iterate through the list and print each one
int count = 0;
if (currentMember == NULL){
printf("There are no family members\n");
}
while (currentMember != NULL) {
count++;
printf("\n\nmember:%d Name:%s Age:%2d POINTING TO:%s\n",
count, currentMember->name,
currentMember->age,
currentMember->next->name);
currentMember = currentMember->next; //move to the next node in the list headed towards NULL
}
}
void CleanUp(Family *head){
Family *freeMe = head;
Family *holdMe = NULL;
while(freeMe != NULL) {
holdMe = freeMe->next;
printf("\nFree Name:%s Age:%d\n",
freeMe->name,
freeMe->age);
free(freeMe);
freeMe = holdMe;
//PrintList(*start);
}
}