繁体   English   中英

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

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

我最近接到了一项任务,要求我创建一个包含私有变量和成员函数/无效函数的 class。 刚刚向我介绍了课程,我的老师给了我一个我不太明白的作业。 我遇到的问题是没有正确输出平均成绩和字母成绩,如下所示。 一切都必须在成员函数中进行。 另外,我是否正确使用了成员函数? 我在网上看到它们是在 class 中定义的,但在我的笔记中我看到它们被引用和处理就像用户定义的 function 一样。 我遇到的困惑是作业的这一部分:

成员函数将每个成员变量设置为作为 function 的参数给出的值,成员函数从每个成员变量中检索数据,一个 void function 计算学生整个课程的加权平均数字分数并设置对应的成员变量,以及一个计算学生最终字母成绩并设置对应成员变量的void function

我的代码如下:

#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 是:

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()将输入的值分配给局部变量,而不是 class 成员变量。 因此,当您想要使用这些 class 成员变量时,它们仍未初始化。

然后,在main()中,您使用了太多student_records实例。 你只需要一个!

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

所以我看到你正在使用 Getter 和 Setter。 这是一个非常好的做法。 为了回答你关于使用成员函数的问题,你已经正确地使用了它们。

您还可以在 class 之外定义成员函数。

谈到您的主要问题,在您的 input() function 中,您没有调用 Setter 函数来设置 class 中的数据成员,因此它们不包含任何值。

您可以在从标准输入获取局部变量后调用设置器。

而且您的局部变量信息似乎也未被使用,如果未使用,请务必评论。

有2个问题:

  • 在 main() 中,您创建了 4 个 student_record 实例,但您只需要其中一个(s,比方说)。 删除其他并将“values.input()”替换为“s.input()”等。
  • 在 input() 中,您不是为 object 的成员变量赋值,而是为 function 结束时忘记的局部变量赋值

让我们看看你在做什么删除student_records info; 来自void input(); ,并且您可以根据自己的意愿进行选择。 如评论中所述,当您声明student_records info; void input()内部,实例info将从 scope 中取出 go 并在input()返回后解构。 (还好没用)

对于类,成员函数和friend元函数可以访问 class private:变量。 如果选择在input()中取输入,可以直接对private: quiz1, quiz2, midterm_exam, final_exam; 不需要任何局部变量。 但是,您也可以选择读取局部变量,然后调用您的 setter 函数,例如void setquiz1 (double q1)将测验 1 的局部变量作为参数传递(这只会增加可忽略不计的开销)。

现在让我们看看您如何尝试在main()中使用 class 实例s 您想要 output 结果:

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

对您现有的 class 进行微小的调整是 100% 可行的。 如果您选择这样做,您将不会使用您的 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;
}

注意:增加了double getweighted_avg ()char getfinalg ()以确保计算weighted_avg并且 getfinalg getfinalg() ) 的返回类型已更改为char 。)

另请注意:每个输入的验证)

示例使用/输出

通过这些更改,您将获得:

$ ./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

现在,在您解释之后,我怀疑您应该做的是将您的界面(您如何与用户交谈并获取输入)与您的实现(您的 class 和您的计算)分离。 这是面向 object 编程的主要目标之一。 不要混合你的接口和实现(它不是花生酱杯)

从这个角度来看,您可以选择是否将input()设为成员 function,或者将其完全分开并将对 class 实例的引用作为参数传递。 将其保留为成员 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();
        }

您将删除对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;
}

(结果是一样的)

所以无论哪种方式都很好,我怀疑最后一种方式更接近你被要求做的事情。 还可以考虑简单地删除input()作为成员 function 并传递引用。 这将完全分离接口和实现。 如果您还有其他问题,请仔细查看并告诉我。

暂无
暂无

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

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