C++指针和数组...何时使用 []、* 和 &



我是一名学生,正在研究一个涉及数组、指针、结构和去引用的问题。我理解每种方法本身的含义以及每种方法的一般初始化,但我觉得我在程序中仍然没有正确使用它们。我的跑步/工作都很好,但我想知道是否有更好的方法来使用这些??

一般程序要求如下:(我已经包含了我认为涵盖每一个问题的行。我想确保我正在正确地使用并将每一行合并到程序中。主要是在我使用StudentData[i].testArray的地方)

1-使用结构存储以下数据:name、id#、test(指向测试分数数组)、平均值、字母等级

struct StudentData {...};

2-询问学生人数和测试次数(每个相同学生)

3-动态分配结构数组

StudentData *allStudents;
allStudents = new StudentData[numStudents];

4-每个结构的测试成员都应该指向一个动态分配的测试分数数组

double *testsArray;
for (int i=0; i < numStudents; i++)
{
    allStudents[i].testsArray = new double[numTests];
}
//does this need to be deleted with a for loop as well??

5-计算测试平均值和字母等级

6-显示信息

完整代码:

// Course Grade
// A program to gather and display a collection of student information. 
// Programmer Name : Chuck
// C++ II
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
//structure to hold data for each student
struct StudentData
{
    string studentName;
    int studentID;
    double *testsArray;     //pointer to an array of test scores
    double testAverage;     //calculated average test score
    char courseGrade;       //calculated course letter grade (A-F)
};

//function prototypes
string getName();
int getID();
double getScore(int count);
char calcGradeLetter(double *testAverage);
void displayData (StudentData allStudents[], int sCount);

int main()
{   cout << "   Welcome to the Test Score Storer. This program will gather testn";
    cout << "scores for a given student name/id#. We'll start with some questions.nn";
    int numTests;
    cout << "How many test scores per student? : ";
    cin  >> numTests;
    int numStudents;
    cout << "How many students?                : ";
    cin  >> numStudents;
    cout << "Creating Database...";
    //create array to hold all studentData structs
    StudentData *allStudents;
    allStudents = new StudentData[numStudents];
    cout << "...";
    //create a tests member array for each student struct
    double *testsArray;
    for (int i=0; i < numStudents; i++)
    {
        allStudents[i].testsArray = new double[numTests];
    }
    cout <<"...Done!n";
    system ("pause");
    system ("CLS");

    //TRYING
    for (int i=0; i < numStudents; i++)
    {
        cout << "Student " << i+1 << " of " << numStudents << endl;
        cout << "=================================n";
        allStudents[i].studentName = getName();
        allStudents[i].studentID = getID();
        double testTotal = 0.0;
        for (int j=0; j < numTests; j++)
        {
            allStudents[i].testsArray[j] = getScore(j);
            testTotal += allStudents[i].testsArray[j];
            allStudents[i].testAverage = testTotal/numTests;
        }
        //calculate letter grade
        allStudents[i].courseGrade = calcGradeLetter(&allStudents[i].testAverage);
        cout << "Student,  " << allStudents[i].studentName << ", completed.n";
        system ("pause");
        system ("CLS");
    }
    //Display all collected student data in chart form
    displayData(allStudents, numStudents);

    delete [] allStudents;
    system ("pause");
    return (0);
}

//===========FUNCTIONS===========FUNCTIONS===========FUNCTIONS
string getName()
{
    string name;
    cout << "Student Name  : ";
    cin  >> name;
    return name;
}
int getID()
{
    int IDnum;
    cout << "Student ID    : ";
    cin  >> IDnum;
    return IDnum;
}
double getScore(int count)
{
    double score;
    score = -500;
    while (score <0)
    {   cout << "Test Score #" << count+1 <<" : ";
        cin  >> score;
        if (score < 0)
        {
            cout << "Scores cannot be less than 0, try again.n";
        }
    }   
    return score;
}

char calcGradeLetter(double *testAverage)
{
    if (*testAverage >= 90) return 'A';
    else if (*testAverage >= 80) return 'B';
    else if (*testAverage >= 70) return 'C';
    else if (*testAverage <  70) return 'F';
    else return ('X');
}
void displayData(StudentData allStudents[], int sCount)
{
    cout << "Student Data Chart:n";
    cout << "=================================================n";
    cout << "NAME               ID#          TEST AVE.   GRADEn";
    for (int i = 0; i < sCount; i++)
    {
        cout << left << setw(18) << allStudents[i].studentName << " "
             << left << setw(12) << allStudents[i].studentID << " "
             << left << setw(11) << setprecision(4) << allStudents[i].testAverage << " "
             << allStudents[i].courseGrade << endl;
    }
    cout << "nTable complete. ";
    }

这是我在Stack上的第一篇文章,很抱歉,如果这篇文章放错了地方,或者给人的印象是需要家庭作业,我不仅仅是在寻找一个简单的答案。我是一个新的开发人员,渴望学习。这个话题只是我在处理时遇到了很多麻烦。

您的问题的简短答案是肯定的,有更好的方法来实现结果。

更长的答案是,由于你的作业的性质,以及你必须特别处理内存分配和释放的要求(顺便说一句,我不知道你在哪里为每个学生分配测试成绩。你需要在删除每个学生并删除测试成绩数组之前对其进行循环),这限制了你使用std::vector之类的东西,它将为您处理所有阵列问题。

只是为了帮助管理内存:

struct StudentData
{
    StudnetData() : studentID(0), testsArray(NULL), testAverage(0.0), courseGrade('N')
    {
    }
    ~StudentData()
    {
        delete [] testsArray;
    }
    string studentName;
    int studentID;
    double *testsArray;     //pointer to an array of test scores
    double testAverage;     //calculated average test score
    char courseGrade;       //calculated course letter grade (A-F)
private:
    StudentData(const StudentData&); // unimplemented intentionally
    StudentData& operator= (const StudentData&); // unimplemented intentionally
};

然后,当您删除学生数组时:

delete [] allStudents;

他们的任何测试也将被删除。

Eh,考虑到您被要求使用new而不是像std::vector这样的类型的标准实践,这在很大程度上是可以的。

C++确实有一些工具可以用来包装new的使用,使其更容易、更安全、更自动化等,同时仍然符合要求。您实际上是在实现vector的简化版本。然而,您可能还没有学会C++的所有必要部分。

structs TestsArray {
  double *scores;
  // constructors, destructors, etc. to make this behave properly
  // ...
};
structs StudentsArray {
  StudentData *students;
  // basically the same as for TestArray; templates avoid this duplication
};

同样,对于等级,您可以定义一个枚举:

enum Grade { A, B, C, D, F};

这样你就不太可能在某个地方遇到无效的分数(例如"e")。

struct StudentData
{
  string studentName;
  int studentID;
  TestsArray testsArray;
  double testAverage;
  Grade courseGrade;
};

cout << "Creating Database...";
//create array to hold all studentData structs
StudentsArray allStudents(numStudents, numTests);
cout <<"...Done!n";
// allStudents will automatically be cleaned up at the end

//这需要用for循环删除吗??

是的,或者至少你需要以某种方式安排删除每个学生的测试数组。

相关内容

  • 没有找到相关文章

最新更新