C++学生成绩类加权平均、最终等级计算异常及成员函数用法疑问
核心运行错误定位
你遇到的输出乱码、结果完全错误的核心原因是main函数中创建了4个完全独立的类实例,所有操作没有作用在同一个对象上:
- 调用
values.input()仅给values对象的考试分数成员完成了赋值 - 后续调用
final_avg.weightavg()时,操作的是完全没有存储任何考试分数、成员全为随机野值的final_avg对象 - 调用
grade.finalg()时,操作的是完全没有加权平均数据的grade对象 - 最终输出时读取的
s对象,从来没有被执行过任何赋值、计算操作,其成员变量是栈上的随机垃圾值,这就是输出出现1.46101e-38这类异常浮点数、等级显示0的根本原因。
除此之外还有两个小问题会影响正确输出:
getfinalg()的返回值类型定义错误:类中final_grade是char字符类型,函数签名却声明为返回double,就算拿到正确的等级字符,也会被强转为数字输出,无法正确显示A/B/C/D/F- 所有私有成员变量没有设置默认初始值,未被赋值时的随机值会干扰计算结果
关于成员函数编写方式的说明
你看到的两种写法都是C++标准允许的,没有对错之分,只是适用场景不同:
- 类内部直接写函数实现:这种写法的函数会被隐式标记为内联函数,适合setter、getter这类逻辑极短的简单函数,优点是写起来紧凑,网上示例多用这种写法
- 类内仅声明函数原型、类外通过
类名::作用域解析符实现:这是课程笔记记录的标准写法,更适合逻辑较长的成员函数,能让类的定义框架更清晰,避免类定义被长函数体撑得臃肿。类外实现的语法示例:
// 类内只写函数声明 class student_records { private: // 私有成员定义 public: void weightavg(); void finalg(); }; // 类外实现,必须绑定类的作用域 void student_records::weightavg() { weighted_avg = ((quiz1 + quiz2)/20 * 0.25 + midterm_exam / 100 * 0.25 + final_exam / 100 * 0.5) * 100; } void student_records::finalg() { // 等级判断逻辑 }
修正后的可运行代码
#include <iostream> #include <cmath> using namespace std; class student_records { private: // 给所有成员设置默认初始值,避免野值问题 double quiz1 = 0, quiz2 = 0, midterm_exam = 0, final_exam = 0; float weighted_avg = 0; char final_grade = ' '; public: // setter 函数保持原有逻辑即可 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'; } // getter 函数修正返回值类型 double getquiz1 () { return quiz1; } double getquiz2 () { return quiz2; } double getmidterm_exam () { return midterm_exam; } double getfinal_exam () { return final_exam; } float getweighted_avg () { return weighted_avg; } // 修正为返回char类型匹配final_grade的类型 char getfinalg () { return final_grade; } }; int main() { // 只创建1个类实例,所有操作都绑定在同一个对象上 student_records s; s.input(); s.weightavg(); s.finalg(); cout << "The average is " << s.getweighted_avg() << " and your final grade is " << s.getfinalg(); return 0; }
修正后验证
按照你之前的测试输入(两个quiz各10分、期中100、期末100),程序会正确输出:The average is 100 and your final grade is A
内容的提问来源于stack exchange,提问作者Neuro
相关产品推荐
相关产品推荐

