我如何阻止这些 if else 语句复合?

How do I stop these if else statements from compounding?

本文关键字:else 语句 复合 if 何阻止      更新时间:2023-10-16

我正在尝试编写一个 c++ 程序,该程序从文本文件中读取输入并使用 10 分评分量表分配成绩,然后在屏幕上打印结果。 我认为我的问题可能与函数 deriveGrade 中的 if else 语句有关,而不是递增枚举,它们似乎在总结增量。任何帮助将不胜感激,谢谢。

#include <iostream>
#include <string>
#include <iomanip>
#include <cmath>
#include <fstream>
using namespace std;
int deriveGrade(double avarage);
enum letter_grade { A, B, C, D, F };
namespace tenPoint
{
letter_grade deriveGrade(double avarage);
char grade;
}
using namespace tenPoint;
int main()
{
string name;
double average;
ifstream inData;    // Is the variable for input data from the file.
inData.open("student_status.txt", ios::in);
while (!inData.eof())
{
getline(inData, name);
inData >> average;
inData.ignore();
grade = ::deriveGrade(average);
cout << name << " " << average << " " << char(grade) << endl;
}
inData.close();
return 0;
}

int deriveGrade(double average)
{

if (average >= 90)
{
grade = static_cast<letter_grade>(grade + 65);
}
else if (average >= 80 && average < 90)
{
grade = static_cast<letter_grade>(grade + 1);
}
else if (average >= 70 && average < 80)
{
grade = static_cast<letter_grade>(grade + 2);
}
else if (average >= 60 && average < 70)
{
grade = static_cast<letter_grade>(grade + 3);
}
else if (average <= 50)
{
grade = static_cast<letter_grade>(grade + 4);
}
else
{
cout << "Invalid entry." << endl;
}
return grade;
}

从文件输入:

多伊、约翰·

93,2

安德鲁斯、苏珊·

84,7

门罗 (马里兰州)

75,1

加斯顿、亚瑟

·62,8

哈波、乔安妮·

42,7

金杰、弗雷德·

95,8

程序输出:

多伊, 约翰· 93.2 A

安德鲁斯, 苏珊 S. 84.7 B

门罗, 马里兰州 75.1 D

加斯顿, 亚瑟 C. 62.8 克

哈波, 乔安妮 Y. 42.7 K

金杰, 弗雷德· 95.8 î

按任意键继续 . . .

程序的逻辑很奇怪,但是可以在不深入任务的情况下给出一些常见的注释。

请注意,当您一一使用if... else语句时,例如

if (average >= 90)
{
grade = static_cast<letter_grade>(grade + 65);
}
else if (average >= 80 && average < 90)
{
grade = static_cast<letter_grade>(grade + 1);
}
...

发现 false 后,无需在else分支中检查average < 90average >= 90。所以至少代码可以更短:

int deriveGrade(double average)
{
if (average >= 90)
{
grade = static_cast<letter_grade>(grade + 65);
}
else if (average >= 80)
{
grade = static_cast<letter_grade>(grade + 1);
}
else if (average >= 70)
{
grade = static_cast<letter_grade>(grade + 2);
}
else if (average >= 60)
{
grade = static_cast<letter_grade>(grade + 3);
}
else if (average <= 50)
{
grade = static_cast<letter_grade>(grade + 4);
}
else // check here! Invalid interval is for values between 50 and 60?
{
cout << "Invalid entry." << endl;
}
return grade;
}

但这并不是显着的改善。最好制作一个公式并使用带有赋值的单个语句来grade = ...

更新:

还有一条评论。如果您知道不可接受值的间隔,请先检查它(在所有其他计算之前):

int deriveGrade(double average)
{
// check the correctness of argument first
if (average > 50 && average < 60)
{
cout << "Invalid entry." << endl; // notification
return  grade; // previous value
// also consider returning special value for error case
}
// calculate value for grade
grade = ...
// return updated value
return grade;
}

"计算成绩值"部分适合您,在编写这部分代码时,请记住:

  • 三元运算对于一种特殊情况很有用,例如grade = (average >= 90)? 65 : floor(100 - average) / 10;

  • 在函数中使用全局值(如grade)是一种不好的做法,并且基于全局变量的初始值是正确的假设来制作逻辑

原因是您在不清除变量的情况下将其添加到grade变量中,因此先前操作的结果在deriveGrade中继承。 我的建议是删除命名空间中的全局char grade;,在deriveGrade中使用局部变量,并在main中使用不同的局部变量。

如果您查看函数代码,如果您的成绩高于 90,grade只会添加 65(以制作 ASCII"A")。然而,每个后续添加都假装这个添加已经发生。相反,如果你确保其他每个 if 不依赖于以前的 if 或 else if 代码,那么你的代码应该更正确。

char deriveGrade( double average )
if( average > 90.0 )
{
return 'A';
}
else if( average > 80.0 )
{
return 'B';
}
...

此解决方案甚至无需在deriveGrade中使用grade变量 使用您精心创建的枚举的更好的替代方案是:

enum letter_grade : char 
{ 
A = 'A', B = 'B', C = 'C', D = 'D', F = 'F' 
};

这允许您通过(char)letter_grade在枚举表示和 char 之间交换(然后您的deriveGrade将返回一个letter_grade)。