簡體   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