#c #linked-list
#c #связанный список
Вопрос:
Я относительно новичок в C и изучал связанные списки с указателями.
Я узнал, что это (*foo).bar
одно и то же объявление foo->bar
. foo->bar
используется, потому что он более удобочитаем.
Поэтому я не понимаю, почему эти фрагменты кода ведут себя по-разному:
1)
void appendCourse(CourseNode** pLL, Course c){
CourseNode * root = *pLL;
CourseNode* last = makeCourseNode(c);
if(root != NULL){
CourseNode node = *root;
while(node.pNext != NULL){
node = *node.pNext;
}
node.pNext = last;
} else {
*pLL = last;
}
}
и
2)
void appendCourse(CourseNode** pLL, Course c){
CourseNode * root = *pLL;
CourseNode* last = makeCourseNode(c);
if(root != NULL){
CourseNode *node = root;
while(node->pNext != NULL){
node = node->pNext;
}
node->pNext = last;
} else {
*pLL = last;
}
}
мне кажется, что 1) должен вести себя так, как если бы сначала выполнялось разыменование, затем доступ к участникам. Вроде как (*foo).bar
но 1), похоже, вообще не работает правильно, он может успешно добавить только первый элемент.
2) однако добавляет все элементы в связанный список.
На случай, если это поможет: мои структуры и другой метод:
typedef struct CourseNode {
struct CourseNode* pNext;
Course course;
} CourseNode;
typedef struct
{
StudentNode *pWaitlistHead; // Waitlist for this course
char szCourseId[12]; // Course Identifier
char szRoom[15]; // Room number of the course
char szDays[15]; // What days the course will meet, ex: MWF, TR, etc
char szTimes[15]; // Meeting Time, ex: 10:00-11:15am
int iAvailSeats; // Number of available seats in the course
double dFee; // Additional fees for the course
} Course;
CourseNode* makeCourseNode(Course c){
CourseNode * node = malloc(sizeof(CourseNode));
node->pNext = NULL;
node->course = c;
return node;
}
Комментарии:
1. Вы создаете локальную копию
CourseNode
, которая не является копией корневого ptr. Если вы покажете код, который вызываетappendCourse
, вам будет легко помочь2. Просто потому, что
(*foo).bar
это не то же самое, что*foo.bar
3. Вы сделали не только синтаксическую десуггерацию, но и семантическое изменение.
Ответ №1:
CourseNode node = *root;
while(node.pNext != NULL){
node = *node.pNext;
}
Это создает новый CourseNode
called node
. Значение этого нового CourseNode
изменено, но это никак не влияет на связанный список.
CourseNode *node = root;
while(node->pNext != NULL){
node = node->pNext;
}
Здесь node
указывает на CourseNode
, который находится в связанном списке.
Самый простой способ понять разницу заключается в том, что первый фрагмент кода создает новые CourseNode
s. Это похоже на разницу между этими двумя:
int foo (int *i)
{
int *j = i; // j is a pointer to the same int i points to
*j = 2; // this changes the value of the int i points to
int j = *i; // this creates a new int
j = 2; // this changes the value of that new int
}