如何修复Result类中result()函数的for循环异常问题?
问题:C++代码中Result类的result()函数计算总分翻倍的问题
我编写的C++代码里,Result类的result()函数内的for循环计算总分时,结果是预期值的两倍。但直接用total_marks = marks[1] + marks[2] + ... + marks[5]的方式计算是正常的,想知道该for循环存在什么问题。完整代码如下:
#include<iostream> using namespace std; class Student{ protected: char name[20]; int roll; int age; public: void input(){ cout<<"Enter name: "; cin>>name; cout<<"Enter roll number: "; cin>>roll; cout<<"Enter age: "; cin>>age; } }; class Test: public Student{ protected: int marks[5]; public: void getMarks(){ cout<<"Enter marks: "<<endl; for(int i=1; i<=5; i++){ cout<<"Subject "<<i<<":"; cin>>marks[i]; } } void displayMarks(){ cout<<"\n"; cout<<"Student Name: "<<name<<endl; cout<<"Student Roll no: "<<roll<<endl; cout<<"Student age: "<<age<<endl; for(int i=1; i<=5; i++){ cout<<"Marks in Suject "<<i<<": "<<marks[i]<<endl; } } }; class Result: public Test{ protected: int total_marks=0; float percentage; public: void result(){ for(int i=1; i<=5; i++){ total_marks = total_marks + marks[i]; } cout<<"Total marks: "<<total_marks<<endl; percentage = (float)total_marks/5; cout<<"Percentage: "<<percentage<<endl; } }; int main(){ Result r; r.input(); r.getMarks(); r.displayMarks(); r.result(); }
问题原因
核心问题是数组越界访问,结合类成员内存布局导致了意外修改:
- C++数组索引从
0开始,你声明的int marks[5];有效索引范围是0~4,但所有循环都用了i从1到5,直接访问了数组之外的内存。 - 根据C++类的成员布局规则,Test类的
marks数组之后,紧接着就是Result类的total_marks成员变量,所以marks[5]的内存地址恰好等于total_marks的地址。 - 在
getMarks()中,你把第五科分数写入marks[5],等同于直接修改了total_marks的初始值(原本为0,现在变成第五科分数)。 - 在
result()的循环中,当循环到i=5时,你会把marks[5](也就是当前total_marks的值,此时已经是前四科分数加第五科分数的初始值)再次加到total_marks里,最终导致总分变成预期值的两倍。
修复方案
遵循C++数组从0开始的索引规则,修改所有循环的逻辑:
- 修改
Test::getMarks()的循环:
void getMarks(){ cout<<"Enter marks: "<<endl; for(int i=0; i<5; i++){ cout<<"Subject "<<(i+1)<<":"; // 显示科目序号时加1,符合用户习惯 cin>>marks[i]; } }
- 修改
Test::displayMarks()的循环:
void displayMarks(){ cout<<"\n"; cout<<"Student Name: "<<name<<endl; cout<<"Student Roll no: "<<roll<<endl; cout<<"Student age: "<<age<<endl; for(int i=0; i<5; i++){ cout<<"Marks in Subject "<<(i+1)<<": "<<marks[i]<<endl; } }
- 修改
Result::result()的循环,同时显式初始化total_marks避免意外:
void result(){ total_marks = 0; // 显式初始化,确保计算前值为0 for(int i=0; i<5; i++){ total_marks += marks[i]; } cout<<"Total marks: "<<total_marks<<endl; percentage = (float)total_marks/5; cout<<"Percentage: "<<percentage<<endl; }
内容的提问来源于stack exchange,提问作者Devansh Kumar
相关产品推荐
相关产品推荐

