我是一名学生,正在研究一个涉及数组、指针、结构和去引用的问题。我理解每种方法本身的含义以及每种方法的一般初始化,但我觉得我在程序中仍然没有正确使用它们。我的跑步/工作都很好,但我想知道是否有更好的方法来使用这些??
一般程序要求如下:(我已经包含了我认为涵盖每一个问题的行。我想确保我正在正确地使用并将每一行合并到程序中。主要是在我使用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循环删除吗??
是的,或者至少你需要以某种方式安排删除每个学生的测试数组。