You have taken-off in somewhat an awkward direction for handling your student data. As mentioned in the comments, whenever you need to coordinate multiple values and/or differing types of data as one unit, you should be thinking struct
or class
. Say you want to create a simple:
struct student {
unsigned id, prelim, midterm, final;
};
Now each student you create will have an id
, a prelim
grade as well as grades for midterm
and final
. Now when you create an array of student
, each element will have each of the variables as a member-variable. (and with a struct
the member access is public:
by default, so you may access the values directly).
You can also declare and initialize all values in an array of student
with simple brace-initializers, e.g.
int main (void) {
student students[] = {{ 1111, 80, 90, 70 }, { 2222, 70, 65, 80 },
{ 3333, 85, 85, 90 }, { 4444, 90, 90, 90 },
{ 5555, 95, 85, 85 } };
Now all you need to do is calculate overall
and output the results. A complete program providing output formatted similar to what is needed could be:
#include <iostream>
struct student {
unsigned id, prelim, midterm, final;
};
int main (void) {
student students[] = {{ 1111, 80, 90, 70 }, { 2222, 70, 65, 80 },
{ 3333, 85, 85, 90 }, { 4444, 90, 90, 90 },
{ 5555, 95, 85, 85 } };
size_t n = sizeof students / sizeof *students;
for (size_t i = 0; i < n; i++) {
double overall = .2 * students[i].prelim +
.3 * students[i].midterm +
.5 * students[i].final;
std::cout << '\t' << students[i].id << "\t\t" <<
students[i].prelim << '\t' <<
students[i].midterm << '\t' <<
students[i].final << '\t' <<
overall << '\t' <<
(overall < .6 ? "Failed" : "Passed") << '\n';
}
}
Example Use/Output
$ ./bin/students_overall_c
1111 80 90 70 78 Passed
2222 70 65 80 73.5 Passed
3333 85 85 90 87.5 Passed
4444 90 90 90 90 Passed
5555 95 85 85 87 Passed
Making Your Struct Smarter
Now if you like, and if you need the overall
value more than once, it would make sense to make that as a double
member-value of your struct
and you could write a short constructor for your struct to automatically calculate the overall
value when initialized.
struct student {
unsigned id, prelim, midterm, final;
double overall;
student (unsigned i, double p, double m, double f) :
id(i), prelim(p), midterm(m), final(f) {
overall=.2 * prelim + .3 * midterm + .5 * final;
}
};
Then all you need to do is initialize your array and print it:
#include <iostream>
struct student {
unsigned id, prelim, midterm, final;
double overall;
student (unsigned i, double p, double m, double f) :
id(i), prelim(p), midterm(m), final(f) {
overall=.2 * prelim + .3 * midterm + .5 * final;
}
};
int main (void) {
student students[] = {{ 1111, 80, 90, 70 }, { 2222, 70, 65, 80 },
{ 3333, 85, 85, 90 }, { 4444, 90, 90, 90 },
{ 5555, 95, 85, 85 } };
size_t n = sizeof students / sizeof *students;
for (size_t i = 0; i < n; i++)
std::cout << '\t' << students[i].id << "\t\t" <<
students[i].prelim << '\t' <<
students[i].midterm << '\t' <<
students[i].final << '\t' <<
students[i].overall << '\t' <<
(students[i].overall < .6 ? "Failed" : "Passed") << '\n';
}
(same output)
Let Your Struct Format Your Output
Since in C++ a struct
and class
have the same properties, you have the ability to overload the <<
operator within your struct to handle output formatting for you and not have to clutter up the logic of main()
will the details. You can add an overload of <<
to your struct as follows:
struct student {
unsigned id, prelim, midterm, final;
double overall;
student (unsigned i, double p, double m, double f) :
id(i), prelim(p), midterm(m), final(f) {
overall=.2 * prelim + .3 * midterm + .5 * final;
}
friend std::ostream& operator<< (std::ostream& os, const student& s) {
std::cout << '\t' << s.id << "\t\t" << s.prelim << '\t' << s.midterm << '\t' <<
s.final << '\t' << s.overall << '\t' << (s.overall < .6 ? "Failed" : "Passed");
return os;
}
};
Now all you do is initialize your array and output each element:
#include <iostream>
struct student {
unsigned id, prelim, midterm, final;
double overall;
student (unsigned i, double p, double m, double f) :
id(i), prelim(p), midterm(m), final(f) {
overall=.2 * prelim + .3 * midterm + .5 * final;
}
friend std::ostream& operator<< (std::ostream& os, const student& s) {
std::cout << '\t' << s.id << "\t\t" << s.prelim << '\t' << s.midterm << '\t' <<
s.final << '\t' << s.overall << '\t' << (s.overall < .6 ? "Failed" : "Passed");
return os;
}
};
int main (void) {
student students[] = {{ 1111, 80, 90, 70 }, { 2222, 70, 65, 80 },
{ 3333, 85, 85, 90 }, { 4444, 90, 90, 90 },
{ 5555, 95, 85, 85 } };
size_t n = sizeof students / sizeof *students;
for (size_t i = 0; i < n; i++)
std::cout << students[i] << '\n';
}
(same output)
By using a struct
to coordinate all of your values as a single object, you eliminate having to try and manually synchronize between multiple arrays by index. This dramatically reduces your programming complexity (and potential for error).
Try it both ways. Go ahead and write out the remainder of your code using multiple arrays. (you can basically initialize your arrays as you have, and then just draw from the output formatting above). The compare the complexity to using a single struct and decide what works best for you. If you haven't got to using a struct
yet in your class, then consider this a preview of things to come.
Additionally, See: Why is “using namespace std;” considered bad practice?. Look things over and let me know if you have further questions.