私は過去 2.5 時間かけてこのリンク リストを作成し、リストの先頭にメモリ アドレスが渡されない理由を理解しようとしました。私のクラスが Java のデータ構造について何を学んでいるかに移る前に、C でリンクされたリストを理解しようとしています。他の質問を調べましたが、なぜ機能しないのかわかりません。私がすべてを理解するために努力してきたコメントを許してください。お時間をいただきありがとうございます。
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);
}
}