首页 > 解决方案 > 我很困惑,所以我应该如何调用该函数来获取输出

问题描述

我对 C++ 和一般编程有点陌生。这是为了练习我到目前为止学到的东西。

创建一个名为的结构Exam,其中包括考试 ID(字符串)、科目名称(字符串)、注册费(双倍)和一周内注册的学生人数(7 天)(整数数组)。

• 编写一个调用的函数,该函数是读取详细信息并将它们存储在考试结构的变量中getExamDetails()的数据类型 。ExamExam

提示:使用给定的函数原型作为

Exam getExamDetails (Exam e);

• 编写一个调用函数,该函数calExamFee() 接受三个参数:考试注册费、一周(7 天)内注册的学生人数数组和数组大小。查找一周内的总考试注册费并将总考试注册打印到屏幕上。

• 在 main 函数中调用getExamDetails()andcalExamFee()打印以下内容

#include <iostream>
#include <string>
using namespace std;

struct Exam
{
    string examID,subject;
    double regFee;
    int numStudent[];
};

Exam getExamDetails(Exam details);
void calExamFee(double regFree,int numStudent[],int size);

int main()
{
  
  
}

Exam getExamDetails(Exam details) //reads the details of the Exam and store them
{
    cout<<"Enter Exam ID : ";
    cin>>details.examID;

    cout<<"Enter Subject : ";
    cin>>details.subject;

    cout<<"Enter registration Fee : ";
    cin>>details.regFee;

    for (int i = 0; i <=7; i++) //store number of students registered during a week (7 days)
    {
        cout<<"Enter number of student "<<i+1<<" : "<<endl;
        cin>>details.numStudent[i];
    }
    return details;
}

void calExamFee(double regFree,int numStudent[],int size)
{
    float totalExamFee=0;

    for (int i = 0; i < size; i++)
    {
        totalExamFee+=numStudent[i];
    }
    
    totalExamFee=totalExamFee*regFree;
    cout<<"Total registration fee during the week:"<<totalExamFee<<endl;
}

标签: c++struct

解决方案


修复你的代码


1. 无界数组

当定义结构时,您的结构成员numStudent没有指定其大小,这在 C++ 中无效,这与 Java 或 C# 等语言不同。您说numStudent将数据保留一周,因此您可以指定大小7

struct Exam
{
    string examID,subject;
    double regFee;
    int numStudent[7];
};

2. 较小的数据类型calExamFee()

您正在接受regFee作为 type 的参数double。但是,您已声明totalExamFee为浮点数,这是一种更小/更窄的数据类型:

float totalExamFee = 0;

由于您正在执行此操作:

totalExamFee = totalExamFee*regFree

float在其中将 a与 a相乘double,您有溢出的风险。要么将类型更改totalExamFee为 a ,要么将类型double更改regFee为 a float

3.非法数组访问

您的 for 循环之一读取for(i = 0; i <= 7; i++). 由于数组大小为 7,因此最大有效索引为6. 所以改成i < 7.

4. 你的main()功能

getExamDetails()接收一个exam,对其作为参数传递的副本执行修改,然后将该副本的另一个副本返回给调用者(main)。这是很多不必要的复制。当您将它作为参数传递时会发生一个副本,而当您将其返回给 main 时会发生另一个副本。我一直保持原样,因为这是问题中指定的原型,现在我们首先专注于修复您的代码。

int main()
{
    // Declare the variable
    Exam exam;
    // Call the input function
    exam = getExamDetails(exam);
    // Calculate the exam fee
    calExamFee(exam.regFee, exam.numStudent, 7);
}

这将为您提供预期的结果,但我们可以改进解决方案并对其进行一些优化。

更好的解决方案


1. 引用传递

的目的getExamDetails是填充字段examID、和 的元素 ,subject这是它的唯一目的。我们不需要昂贵的复制,同时接受它作为参数,然后再返回它。我们可以通过在 main to 中接受对同一变量的引用而不是复制它来防止复制。这称为传递被引用,这就是我们如何实现它:regFeenumStudentexamgetExamDetails

void getExamDetails1(Exam& exam)
{
    cout<<"Enter Exam ID : ";
    cin>>exam.examID;

    cout<<"Enter Subject : ";
    cin>>exam.subject;

    cout<<"Enter registration Fee : ";
    cin>>exam.regFee;

    for (int i = 0; i < 7; i++) //store number of students registered during a week (7 days)
    {
        cout<<"Enter number of student "<<i+1<<" : "<<endl;
        cin>>exam.numStudent[i];
    }
}

main

Exam exam;
getExamDetails(exam);

注意&后面Exam。这告诉函数在接受变量时不要从中复制变量main。向我发送与 main 中相同变量的引用。由于它接受引用而不是副本,因此任何更改details也将反映在main'sexam变量中。看看返回类型现在是如何void而不是Exam. 我们不需要返回一个,exam因为所有的变化都已经反映在main'sexam变量中。

2.一个功能,一件事

根据单一职责原则,每个职能部门必须只做一项工作。你calExamFee做了两件事。计算考试费用并打印出来。让它为您执行计算并返回结果:

double calExamFee(double regFree,int numStudent[],int size)
{
    double totalExamFee = 0;

    for (int i = 0; i < size; i++)
    {
        totalExamFee += numStudent[i];
    }
    
    totalExamFee = totalExamFee*regFree;
    return totalExamFee;
}

main

double totalFee = calExamFee(exam.regFee, exam.numStudent, 7);
cout << "Total registration fee during the week: " << totalFee << endl;

甚至:

cout << "Total registration fee during the week: " << calExamFee(exam.regFee, exam.numStudent, 7) << endl;

打印结果的任务现在委托给main.

此外,数组大小似乎始终为7,因此您无需传递它,只需对值进行硬编码:

double calExamFee(double regFree,int numStudent[])

i < 7在循环中使用。


推荐阅读