[英]C pointer does not get set after being passed to a function
因此,我花了一段时间学习C语言,终于碰到了墙。 我在网上发现了不同的练习问题,而我确实遇到了问题。
起初,我写了这个代码的所有主要功能内,它工作得很好,并给出所需的输出(这里是工作的例子)
#include <stdio.h>
#include <stdlib.h>
typedef struct Student STUDENT;
typedef struct Teacher TEACHER;
typedef struct Course COURSE;
int addStudentToTree(STUDENT *students, STUDENT *newStudent, STUDENT *currentStudent);
void printStudents(STUDENT *s);
struct Student
{
int StudentNumber;
char FirstName[BUFSIZ];
STUDENT *left, *right;
};
struct Teacher
{
int TeacherNumber;
char FirstName[BUFSIZ];
TEACHER *left, *right;
};
struct Course
{
int CourseNumber;
char CourseName[BUFSIZ];
int SemesterNumber;
COURSE *left, *right;
};
int main()
{
FILE *db = fopen("DatabaseFile.txt", "r");
char line[BUFSIZ];
STUDENT *newStudent, *currentStudent, *students;
students = NULL;
if (db != NULL)
{
while (fgets(line, sizeof(line), db) != NULL)
{
if (line[0] == 'S')
{
newStudent = malloc(sizeof(STUDENT));
if (sscanf(line, "S %d %s", &newStudent->StudentNumber, newStudent->FirstName) == 2)
{
newStudent->left = NULL;
newStudent->right = NULL;
if (students == NULL)
{
students = newStudent;
}
else
{
currentStudent = students;
while(currentStudent)
{
if (newStudent->StudentNumber != currentStudent->StudentNumber)
{
if (newStudent->StudentNumber < currentStudent->StudentNumber)
{
if (currentStudent->left == NULL)
{
currentStudent->left = newStudent;
break;
}
else
{
currentStudent = currentStudent->left;
}
}
else
{
if (currentStudent->right == NULL)
{
currentStudent->right = newStudent;
break;
}
else
{
currentStudent = currentStudent->right;
}
}
}
}
}
}
}
}
}
printStudents(students);
}
它成功地填充了树,然后遍历它以提供以下输出:
Student Number: 203214 Student Name: Agneta
Student Number: 208214 Student Name: Janeta
Student Number: 213363 Student Name: Jill
Student Number: 215263 Student Name: Hansi
Student Number: 215363 Student Name: Laurent
Student Number: 228214 Student Name: James
现在,实践问题的一部分也正在将其移到函数中,因此所有内容都不仅在main方法中运行。
我这样做是这样的:
#include <stdio.h>
#include <stdlib.h>
typedef struct Student STUDENT;
typedef struct Teacher TEACHER;
typedef struct Course COURSE;
int addStudentToTree(STUDENT *students, STUDENT *newStudent, STUDENT *currentStudent);
void printStudents(STUDENT *s);
struct Student
{
int StudentNumber;
char FirstName[BUFSIZ];
STUDENT *left, *right;
};
struct Teacher
{
int TeacherNumber;
char FirstName[BUFSIZ];
TEACHER *left, *right;
};
struct Course
{
int CourseNumber;
char CourseName[BUFSIZ];
int SemesterNumber;
COURSE *left, *right;
};
int main()
{
FILE *db = fopen("DatabaseFile.txt", "r");
char line[BUFSIZ];
STUDENT *newStudent, *currentStudent, *students;
students = NULL;
if (db != NULL)
{
while (fgets(line, sizeof(line), db) != NULL)
{
if (line[0] == 'S')
{
newStudent = malloc(sizeof(STUDENT));
if (sscanf(line, "S %d %s", &newStudent->StudentNumber, newStudent->FirstName) == 2)
{
newStudent->left = NULL;
newStudent->right = NULL;
addStudentToTree(students, newStudent, currentStudent);
}
}
}
}
printStudents(students);
}
int addStudentToTree(STUDENT *students, STUDENT *newStudent, STUDENT *currentStudent)
{
if (students == NULL)
{
students = newStudent;
return 1;
}
else
{
currentStudent = students;
while(currentStudent)
{
if (newStudent->StudentNumber != currentStudent->StudentNumber)
{
if (newStudent->StudentNumber < currentStudent->StudentNumber)
{
if (currentStudent->left == NULL)
{
currentStudent->left = newStudent;
return 1;
}
else
{
currentStudent = currentStudent->left;
}
}
else
{
if (currentStudent->right == NULL)
{
currentStudent->right = newStudent;
return 1;
}
else
{
currentStudent = currentStudent->right;
}
}
}
}
}
return 0;
}
现在问题来了。 我传入了指针“ students”,并且在第一次传递它时,它是一个空指针,并且被函数中的if语句正确捕获了。 newStudent变量指向一个内存地址。
在这些行之后:
if (students == NULL)
{
students = newStudent;
return 1;
}
指针“学生”现在指向实际地址。 但是,在返回main方法中的while循环之后,“ students”指针再次是NULL指针。
作为附加信息,您可以看到将这些printf放入:
if (students == NULL)
{
printf("students: %p, newStudent: %p\n",students, newStudent );
students = newStudent;
printf("students: %p\n",students);
return 1;
}
产生以下输出:
students: 0x0, newStudent: 0x7fc6e2001200
students: 0x7fc6e2001200
students: 0x0, newStudent: 0x7fc6e2001800
students: 0x7fc6e2001800
students: 0x0, newStudent: 0x7fc6e2005200
students: 0x7fc6e2005200
students: 0x0, newStudent: 0x7fc6e2005800
students: 0x7fc6e2005800
students: 0x0, newStudent: 0x7fc6e2005e00
students: 0x7fc6e2005e00
students: 0x0, newStudent: 0x7fc6e2006400
students: 0x7fc6e2006400
我真的已经花了很多时间在这上面,最后还是屈服于进来问大家。 让我知道您是否还有其他需要澄清的问题。
彼得
您需要传递指针的地址...在这种情况下,参数是在堆栈上创建的,当函数退出时,堆栈将展开,并且您的参数不再有效
int addStudentToTree(STUDENT **students, STUDENT *newStudent, STUDENT *currentStudent);
像
addStudentToTree(学生,newStudent,currentStudent);
在功能上喜欢
* sudents = NULL;
希望能有所帮助
想象一下:
void func(int var)
{
var = 1;
}
int main()
{
int var = 0;
func(var);
// What is the value of 'var' at this point?
...
}
如果您对上述问题的回答为1
,那么您可能应该回到基础知识并从头开始学习该语言。
如果您确实知道函数main
的变量var
的副本保留了其“原始”值,那么您理解分配给函数printStudents
内的可变students
(副本)的任何值都不会生效,您应该没有任何问题。该功能之外。
话虽如此,这是通过引用传递此变量的一般准则:
*
printStudents(STUDENT** s)
printStudents
对该变量所做的每个引用中都添加*
&
printStudents(&s)
- printStudents(&s)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.