简体   繁体   English

确定最终成绩和平均成绩的课程代码不起作用

[英]Classes code to determine final grade and average not working

I recently got an assignment that tasks me to create a class which contains private variables and member functions/void functions.我最近接到了一项任务,要求我创建一个包含私有变量和成员函数/无效函数的 class。 Classes have just been introduced to me and my teacher gave me an assignment that I don't really understand.刚刚向我介绍了课程,我的老师给了我一个我不太明白的作业。 The issue I'm having is that the average and letter grade aren't correctly being outputted as shown below.我遇到的问题是没有正确输出平均成绩和字母成绩,如下所示。 Everything has to take place within the member functions.一切都必须在成员函数中进行。 Also, am I using the member functions correctly?另外,我是否正确使用了成员函数? I've seen online that they are being defined within the class but in my notes I see that they are referenced and treated just like a user defined function.我在网上看到它们是在 class 中定义的,但在我的笔记中我看到它们被引用和处理就像用户定义的 function 一样。 The confusion I'm having is this part of the assignment:我遇到的困惑是作业的这一部分:

member functions to set each of the member variables to values given as an argument(s) to the function, member functions to retrieve the data from each of the member variables, a void function that calculates the student's weighted average numeric score for the entire course and sets the corresponding member variable, and a void function that calculates the student's final letter grade and sets the corresponding member variable成员函数将每个成员变量设置为作为 function 的参数给出的值,成员函数从每个成员变量中检索数据,一个 void function 计算学生整个课程的加权平均数字分数并设置对应的成员变量,以及一个计算学生最终字母成绩并设置对应成员变量的void function

My code is below:我的代码如下:

#include <iostream>
#include <cmath>

using namespace std;

class student_records
{
    private:
        double quiz1, quiz2, midterm_exam, final_exam;
        float weighted_avg;
        char final_grade;

    public:
        void setquiz1 (double q1)
        {
            quiz1 = q1;
        }
        void setquiz2 (double q2)
        {
            quiz2 = q2;
        }
        void setmidterm_exam (double mid)
        {
            midterm_exam = mid;
        }
        void setfinal_exam (double finale)
        {
            final_exam = finale;
        }

        void input()
        {
            cout << "Welcome to the Grading Program! Please enter the following information\n";

            cout << "Enter Quiz 1 and 2 results out of 10 points: ";
            cin >> quiz1 >> quiz2;

            cout << "Enter Mid-term result out of 100 points: ";
            cin >> midterm_exam;

            cout << "Enter Final exam result out of 100 points: ";
            cin >> final_exam;
        }

        void weightavg ()
        {
            weighted_avg = ((quiz1 + quiz2)/20 * 0.25 + midterm_exam / 100 * 0.25 + final_exam / 100 * 0.5) * 100;
        }

        void finalg ()
        {
            if (weighted_avg >= 90)
    {
        final_grade = 'A';
    }
    else if (weighted_avg >= 80)
    {
        final_grade = 'B';
    }
    else if (weighted_avg >= 70)
    {
        final_grade = 'C';
    }
    else if (weighted_avg >= 60)
    {
        final_grade = 'D';
    }
    else
    {
        final_grade = 'F';
    }
        }

        double getquiz1 ()
        {
            return (quiz1);
        }
        double getquiz2 ()
        {
            return (quiz2);
        }
        double getmidterm_exam ()
        {
            return (midterm_exam);
        }
        double getfinal_exam ()
        {
            return (final_exam);
        }
        double getweighted_avg ()
        {
            return (weighted_avg);
        }
        double getfinalg ()
        {
            return (final_grade);
        }

};

int main()
{
    student_records values, final_avg, grade, s;

    values.input();
    final_avg.weightavg();
    grade.finalg();

    cout << "The average is " << s.getweighted_avg() << " and your final grade is " << s.getfinalg();
    return 0;
}

Output is: Output 是:

Welcome to the Grading Program! Please enter the following information
Enter Quiz 1 and 2 results out of 10 points: 10
10
Enter Mid-term result out of 100 points: 100
Enter Final exam result out of 100 points: 100
The average is 1.46101e-38 and your final grade is 0

student_records::input() is assigning the inputted values to local variables, and not to the class member variables. student_records::input()将输入的值分配给局部变量,而不是 class 成员变量。 So these class member variables remain uninitialized by the time you come to wanting to use them.因此,当您想要使用这些 class 成员变量时,它们仍未初始化。

Then, in main() you use too many instances of student_records .然后,在main()中,您使用了太多student_records实例。 You only need one!你只需要一个!

student_records s;
s.input();
s.weightavg();
s.finalg();

So I see you are using Getters and Setters.所以我看到你正在使用 Getter 和 Setter。 That is a really good practice.这是一个非常好的做法。 And to answer your question on using member functions, you have used them correctly.为了回答你关于使用成员函数的问题,你已经正确地使用了它们。

You can also define the member functions outside the class.您还可以在 class 之外定义成员函数。

Coming to your main question, in your input() function you have not called the Setter functions to set the data members in your class hence they do not hold any value.谈到您的主要问题,在您的 input() function 中,您没有调用 Setter 函数来设置 class 中的数据成员,因此它们不包含任何值。

You can call the setters after getting the local variables from stdin.您可以在从标准输入获取局部变量后调用设置器。

And it also seems like your local variable info is being unused, make sure to comment that if not in use.而且您的局部变量信息似乎也未被使用,如果未使用,请务必评论。

There are 2 problems:有2个问题:

  • In main(), you create 4 instances of student_record, but you need only one of them (s, let´s say).在 main() 中,您创建了 4 个 student_record 实例,但您只需要其中一个(s,比方说)。 Remove the others and replace “values.input()” with “s.input()” etc.删除其他并将“values.input()”替换为“s.input()”等。
  • In input(), you assing values not to the member variables of the object, but to the local variables that are forgotten when the function ends在 input() 中,您不是为 object 的成员变量赋值,而是为 function 结束时忘记的局部变量赋值

Let's look at what you are doing removing student_records info;让我们看看你在做什么删除student_records info; from void input();来自void input(); , and you have a choice depending on how you want to do it. ,并且您可以根据自己的意愿进行选择。 As mentioned in the comments, when you declare student_records info;如评论中所述,当您声明student_records info; inside void input() , the instance info will go out of scope and be deconstructed after input() returns.void input()内部,实例info将从 scope 中取出 go 并在input()返回后解构。 (good thing it is unused) (还好没用)

With classes, member functions and friend functions have access to the class private: variables.对于类,成员函数和friend元函数可以访问 class private:变量。 If you choose to take input in input() , you can operated directly on the private: variables quiz1, quiz2, midterm_exam, final_exam;如果选择在input()中取输入,可以直接对private: quiz1, quiz2, midterm_exam, final_exam; without needing any local variabled.不需要任何局部变量。 However, you can also choose to read into local variables and then call your setter functions, eg void setquiz1 (double q1) passing the local variable for quiz 1 as a parameter (this just adds negligible bit of overhead).但是,您也可以选择读取局部变量,然后调用您的 setter 函数,例如void setquiz1 (double q1)将测验 1 的局部变量作为参数传递(这只会增加可忽略不计的开销)。

Now let's look at how you try and use the class instance s in main() .现在让我们看看您如何尝试在main()中使用 class 实例s You want to output results with:您想要 output 结果:

    std::cout << "The average is " << s.getweighted_avg() << 
                " and your final grade is " << s.getfinalg() << '\n';

Which is 100% doable with tiny tweaks to your existing class.对您现有的 class 进行微小的调整是 100% 可行的。 If you choose to do it that way, you are not using your getters and setters, but rather you are doing the following:如果您选择这样做,您将不会使用您的 getter 和 setter,而是您正在执行以下操作:

#include <iostream>

class student_records
{
    private:
        double quiz1, quiz2, midterm_exam, final_exam;
        float weighted_avg;
        char final_grade;

    public:
        void input()
        {
            std::cout << "Welcome to the Grading Program! "
                         "Please enter the following information\n";

            std::cout << "Enter Quiz 1 and 2 results out of 10 points: ";
            if (!(std::cin >> quiz1 >> quiz2)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            
            std::cout << "Enter Mid-term result out of 100 points: ";
            if (!(std::cin >> midterm_exam)) {
                std::cerr << "error: numeric input.\n";
                return;
            }

            std::cout << "Enter Final exam result out of 100 points: ";
            if (!(std::cin >> final_exam)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
        }

        void weightavg ()
        {
            weighted_avg = ((quiz1 + quiz2)/20 * 0.25 + midterm_exam / 100 * 0.25 +
                            final_exam / 100 * 0.5) * 100;
        }

        void finalg ()
        {
            if (weighted_avg >= 90)
            {
                final_grade = 'A';
            }
            else if (weighted_avg >= 80)
            {
                final_grade = 'B';
            }
            else if (weighted_avg >= 70)
            {
                final_grade = 'C';
            }
            else if (weighted_avg >= 60)
            {
                final_grade = 'D';
            }
            else
            {
                final_grade = 'F';
            }
        }

        double getweighted_avg ()
        {
            weightavg();
            return (weighted_avg);
        }
        char getfinalg ()
        {
            finalg();
            return (final_grade);
        }

};

int main ()
{
    student_records s{};
    
    s.input();
    
    std::cout << "The average is " << s.getweighted_avg() << 
                " and your final grade is " << s.getfinalg() << '\n';
    return 0;
}

( note: the addition to double getweighted_avg () and char getfinalg () to ensure weighted_avg is calculated and the return type for getfinalg() has been changed to char .) 注意:增加了double getweighted_avg ()char getfinalg ()以确保计算weighted_avg并且 getfinalg getfinalg() ) 的返回类型已更改为char 。)

( also note: the validation of EVERY input) 另请注意:每个输入的验证)

Example Use/Output示例使用/输出

With those changes, you would get:通过这些更改,您将获得:

$ ./bin/student_weighted_avg
Welcome to the Grading Program! Please enter the following information
Enter Quiz 1 and 2 results out of 10 points: 10 10
Enter Mid-term result out of 100 points: 100
Enter Final exam result out of 100 points: 100
The average is 100 and your final grade is A

Now after your explanation, I suspect you are supposed to do is decouple your interface (how you talk to the user and get input) from your implementation (your class and your calculations).现在,在您解释之后,我怀疑您应该做的是将您的界面(您如何与用户交谈并获取输入)与您的实现(您的 class 和您的计算)分离。 That is one of the primary goals in object oriented programming.这是面向 object 编程的主要目标之一。 Don't mix your interface and implementation (it's not a peanut butter cup)不要混合你的接口和实现(它不是花生酱杯)

From that standpoint, you can choose whether to make input() a member function, or make it wholly separate and pass a reference to a class instance as a parameter.从这个角度来看,您可以选择是否将input()设为成员 function,或者将其完全分开并将对 class 实例的引用作为参数传递。 Leaving it as a member function, you would then do:将其保留为成员 function,然后您将执行以下操作:

        void input()
        {
            double q1, q2, mt, fe;
            
            std::cout << "Welcome to the Grading Program! "
                            "Please enter the following information\n";
        
            std::cout << "Enter Quiz 1 and 2 results out of 10 points: ";
            if (!(std::cin >> q1 >> q2)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setquiz1 (q1);
            setquiz2 (q2);
            
            std::cout << "Enter Mid-term result out of 100 points: ";
            if (!(std::cin >> mt)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setmidterm_exam(mt);
        
            std::cout << "Enter Final exam result out of 100 points: ";
            if (!(std::cin >> fe)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setfinal_exam(fe);
            
            weightavg();
            finalg();
        }

You would remove the additions to getweighted_avg() and getfinalg() , so your entire code would work as:您将删除对getweighted_avg()getfinalg()的添加,因此您的整个代码将按以下方式工作:

#include <iostream>

class student_records
{
    private:
        double quiz1, quiz2, midterm_exam, final_exam;
        float weighted_avg;
        char final_grade;

    public:
        void setquiz1 (double q1)
        {
            quiz1 = q1;
        }
        void setquiz2 (double q2)
        {
            quiz2 = q2;
        }
        void setmidterm_exam (double mid)
        {
            midterm_exam = mid;
        }
        void setfinal_exam (double finale)
        {
            final_exam = finale;
        }

        void input()
        {
            double q1, q2, mt, fe;
            
            std::cout << "Welcome to the Grading Program! "
                            "Please enter the following information\n";
        
            std::cout << "Enter Quiz 1 and 2 results out of 10 points: ";
            if (!(std::cin >> q1 >> q2)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setquiz1 (q1);
            setquiz2 (q2);
            
            std::cout << "Enter Mid-term result out of 100 points: ";
            if (!(std::cin >> mt)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setmidterm_exam(mt);
        
            std::cout << "Enter Final exam result out of 100 points: ";
            if (!(std::cin >> fe)) {
                std::cerr << "error: numeric input.\n";
                return;
            }
            setfinal_exam(fe);
            
            weightavg();
            finalg();
        }
        
        void weightavg ()
        {
            weighted_avg = ((quiz1 + quiz2)/20 * 0.25 + midterm_exam / 100 * 0.25 +
                            final_exam / 100 * 0.5) * 100;
        }

        void finalg ()
        {
            if (weighted_avg >= 90)
            {
                final_grade = 'A';
            }
            else if (weighted_avg >= 80)
            {
                final_grade = 'B';
            }
            else if (weighted_avg >= 70)
            {
                final_grade = 'C';
            }
            else if (weighted_avg >= 60)
            {
                final_grade = 'D';
            }
            else
            {
                final_grade = 'F';
            }
        }

        double getquiz1 ()
        {
            return (quiz1);
        }
        double getquiz2 ()
        {
            return (quiz2);
        }
        double getmidterm_exam ()
        {
            return (midterm_exam);
        }
        double getfinal_exam ()
        {
            return (final_exam);
        }
        double getweighted_avg ()
        {
            return (weighted_avg);
        }
        char getfinalg ()
        {
            return (final_grade);
        }

};

int main ()
{
    student_records s{};
    
    s.input();
    
    std::cout << "The average is " << s.getweighted_avg() << 
                " and your final grade is " << s.getfinalg() << '\n';
    return 0;
}

(result is the same) (结果是一样的)

So either way is fine, I suspect this last way is closer to what you are asked to do.所以无论哪种方式都很好,我怀疑最后一种方式更接近你被要求做的事情。 Consider also simply removing input() as a member function and passing a reference.还可以考虑简单地删除input()作为成员 function 并传递引用。 That would completely separate interface and implementation.这将完全分离接口和实现。 Look things over and let me know if you have further questions.如果您还有其他问题,请仔细查看并告诉我。

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

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