Hello, I have to write a program which allows the input of a student's id, name and marks in 4 different subjects using a function input_stud and another function calculate_over to calculate his overall percentage of marks(the total exam marks are 400). I have been able to get the first function right but the function calculate_over is not displaying the correct percentage and I am not permitted to use pointers.
Here is what I have worked out so far:
Any improvisations and modifications would be greatly appreciated.
#include <iostream>
using namespace std;
struct student
{
int id;
string surname;
string othername;
int marks1,marks2,marks3,marks4,total;
double avg;
};
void input_stud(student);
student calculate_over(student&);
int main()
{
student s, z;
input_stud (s);
z=calculate_over(s);
cout<< "The overall percentage is:"<<z.avg<< " %"<<endl;
return 0;
}
void input_stud (student std)
{
cout<< "\nEnter the following details of the student. "<<endl;
cout<< "\n ID number:";
cin>>std.id;
cout<< "\n Surname:";
cin>>std.surname;
cout<< "\n Other names:";
cin>>std.othername;
cout<< "\n Marks obtained:";
cout<< "\n Subject 1:";
cin>>std.marks1;
Problem is in your input_stud function. It does nothing. It receives a copy of some struct, changes it... and that is all. No changes would be visible outside.
You need to pass structure as reference, as you did in calculate_over.
Additionally there is a problem with average claculation in calculate_over.
Quiz time: what is the result of (399/400)*100?
Time is up, answer is: 0. As 399/400 is 0. You are performing integer division here. which discards fractional part.
Easiest way to fix it is to make total double. This wy you will force floating point division and everything will be all right.
@MiNiPaa I have understood what u said about the average calculation so I have made total of type double but I am not sure if I have quite got what you have said about the input_stud function. I have come up with this but it is still not displaying the correct avg.
#include <iostream>
using namespace std;
struct student
{
int id;
string surname;
string othername;
int marks1,marks2,marks3,marks4;
double avg;
};
void input_stud(student);
student calculate_over(student&);
int main()
{
student s;
input_stud (s);
calculate_over(s);
return 0;
}
void input_stud (student std)
{
cout<< "\nEnter the following details of the student. "<<endl;
cout<< "\n ID number:";
cin>>std.id;
cout<< "\n Surname:";
cin>>std.surname;
cout<< "\n Other names:";
cin>>std.othername;
cout<< "\n Marks obtained:";
cout<< "\n Subject 1:";
cin>>std.marks1;
cout<< "\n Subject 2:";
cin>>std.marks2;
cout<< "\n Subject 3:";
cin>>std.marks3;
cout<< "\n Subject 4:";
cin>>std.marks4;
cout<< "The overall percentage is:"<<std.avg<< " %"<<endl;
int main()
{
student s; //Creates s filled with random data
input_stud (s); //Does not change s at all as it was passed by copy
std::cout << s.mark1 << '\n'; //Look for yourself
calculate_over(s); //Calls function, s contains random data
}
Quiz: what the difference between
1 2 3
(student )
//and
(student&)
and how one or other wuld change program execution.
Well... I think both (student) and (student&) access the same data structure that is struct student.
Actually, this is my first question working with passing structure to two functions so I am really at a loss at this.
I think both (student) and (student&) access the same data structure that is struct student.
So, what that & means and why do you have it in calculate_over(student&); and don't in input_stud(student);? (actual question. Why did you write like this?)
The answer is, something like void foo(int ) passes by copy and all operations inside function are done on copy:
1 2 3 4 5 6 7 8 9 10 11
int foo(int i) //Copies argument into i
{
i = 5; //Changes copy
} //i is destroyed here. There is no way to read its value now
int main()
{
int x = 0; //Create variable
foo(x); //Copy x into foo and operate on copy
//x here is still 0, as it was not changed in function
}
On the other hand something like void foo(int&) is passed by reference, which means that operations would be applied to passed variable:
1 2 3 4 5 6 7 8 9 10 11
void foo(int& i) //I is a reference to passed argument. Any changes to i will be reflected on passed variable
{
i = 5; //Sets whichever variable was passed to 5;
}
int main()
{
int x = 0;
foo(x); //Pass x to function. foo changes value of x
//x is now 5
}
cout<< "The overall percentage is:"<<std.answer<< " %"<<endl;
You are printing out answer here (on line 60). But you never assign anything to it so you will get garbage being printed out. You read in marks, but do nothing with them.
& is like an alias to that object. If you change the alias you change the object.
That's what you need.
If you pass by value you have to return that value at the end of the function. return std; But!!! Then you also have to implement a copy constructor. (see deep and shallow copy) to know why and change your function to have a return value. IF you copy by value your data even doesn't get into your fuction without the copy Constructor.
I have finally understood the whole concept.
Thank you everyone for your help.
I immensely appreciate the quick responses to my question and as a first-timer on a forum (and this being my first question on a forum) it's nice to be here and to see so many people volunteering to help and explain the concepts.