繁体   English   中英

传递给函数后C指针未设置

[英]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 (副本)的任何值都不会生效,您应该没有任何问题。该功能之外。

话虽如此,这是通过引用传递此变量的一般准则:

  1. 在函数声明中的变量类型中添加* printStudents(STUDENT** s)
  2. 在函数printStudents对该变量所做的每个引用中都添加*
  3. 在调用函数的每个位置的变量前添加& printStudents(&s) - printStudents(&s)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM