-3

I did not find anywhere the answer for my issue, I am pretty new to OOP so please give me mercy. Okay so I have the following code:

class Group
{
public:
    struct Student
    {
        char name[40],
        int grades[5]};
    }

    Student s[10];

    .....

    private: double med(???)
    {
        .....
    }
}

So where's ??? I want to have as parameters the grades of an individual student and return the average of them. I don't know how should I declare them, I tried in many ways but I get errors everytime.

Ty a lot

Błażej Michalik
  • 4,474
  • 40
  • 55
  • Your `Student` struct in side wrapped with `Group` class. so you need to create a class object and then only then you can use it – Ravi Makwana Feb 05 '20 at 14:01
  • Are you sure you want to pass the *grades* of a student and not just the name? That way you could do `group.med("Suzy")` (corresponding prototype is `double med(const char * name)`). Of course it is up to you how to handle non-existing students, perhaps returning -1 is a good idea. – Botje Feb 05 '20 at 14:03
  • To be fair, the syntax for passing a raw array into a function can be a bit weird, which is one reason why it is recommended to use [std::array](https://en.cppreference.com/w/cpp/container/array) or [std::vector](https://en.cppreference.com/w/cpp/container/vector) instead. If you *really* insist on sticking with raw arrays, you need something like `double med(int (&grades)[5])`. – 0x5453 Feb 05 '20 at 14:05
  • @Botje well the students are not non-existing. I have all their names and grades, I just need to return the avg of their grades by every individual student. As a only parameter, I should have s[i].notes[5] but I m having troubles with the syntax part. I dont know and I couldnt find any answer for this particular case. – stackedfulldiamonds Feb 05 '20 at 14:12
  • If you want to pass in the grades, why don't you just do so? Or what problem are you facing while trying to do so? – mfnx Feb 05 '20 at 14:28
  • @stackedfulldiamonds If you want to return the average grade per student, that will not fit in a `double` return type. Either you return an a collection of averages (an array of averages `double[]` or preferably an `std::map`) , OR you need to specify for which student you want the average. – Botje Feb 05 '20 at 14:35
  • @Botje He wants to pass the grades of an individual student, so it should fit in a double. – mfnx Feb 05 '20 at 14:36
  • IMHO, nested classes or structs complicate programs. Move the `Student` class to separate files (.hpp for the declaration, .cpp for the implementation). – Thomas Matthews Feb 05 '20 at 16:00

2 Answers2

2

So you have a struct with parameters, like:

struct Student
{
    std::string name;
    std::array<int, 5> grades;
};

Since this is tagged C++, I chose to use a std::array<int, 5> rather than int[5].

In my opinion, Student should not be necessarily inside of Group, but I guess that's opinion based.

Now you have a Group which contains students:

struct Group
{
    Group(std::vector<Student> students) :
        _students{ std::move(students) }
    {}

    double med(/* ... */) const
    { /* ... */ }

    std::vector<Student> _students; // C++ -> use std::vector
};

Say you want to pass the grades of a particular student as parameter of the function med, than you would simply do:

double Group::med(const std::array<int, 5>& grades) const
{ /* sum up grades, divide by 5, and return the result */ }

And you would call this function as follows:

Student paul{"Paul", {1,2,3,4,5}};
Group group({paul});
group.med(paul.grades);

As suggested in the comments, you might want to pass the name of a student instead of his/her grades:

double med(const std::string& name)
{
    // find student
    auto it = std::find_if(_students.begin(), _students.end(), [&name](const Student& student)
    {
        return student.name == name;
    });

    // if no student by that name
    if (it == _students.end())
        return -1.0;

    // else    
    int sum{ 0 };
    for (const auto& grade : it->grades)
    {
        sum += grade;
    }
    return static_cast<double>(sum)/(it->grades.size());
}

Here is a discussion about good C++ books.

mfnx
  • 2,894
  • 1
  • 12
  • 28
0

Tyr this code Contains four avg() functions all are same but differ in how the functions are called.

#include<iostream>
#include<string.h>

using namespace std;

class Group
{
 public:
    struct Student
    {
        char name[40];
        int grades[5];

    }student;

    double avg()
    {
        double sum=0;

        for(int i=0;i<5;i++)
            sum+=student.grades[i];

        return (sum/5);
    }
};

double avg(int *grade)
{
    double sum=0;

    for(int i=0;i<5;i++)
        sum+=grade[i];

    return (sum/5);
}

double avg(Group::Student stduent)
{
   double sum=0;

    for(int i=0;i<5;i++)
        sum+=stduent.grades[i];

    return (sum/5);
}

double avg(Group group)
{
    double sum=0;

    for(int i=0;i<5;i++)
        sum+=group.student.grades[i];

    return (sum/5);
}

int main()
{
    Group group1;

    strcpy(group1.student.name,"MyName");

    for(int i=0;i<5;i++)
    group1.student.grades[i]=5;

    cout<<"Name:"<<group1.student.name<<endl;
    cout<<"Avg:"<<avg(group1.student.grades)<<" "<<avg(group1.student)<<" "<<avg(group1)<<" "<<group1.avg();

    return 0;
}

Output:

Name:MyName
Avg:5 5 5 5
Process returned 0 (0x0)   execution time : 0.379 s
Press any key to continue.

You may leave the structure unnamed like

  struct
  {
    char name[40];
    int grades[5];
  }student;

If you delete the function and function call from the code

double avg(Group::Student stduent)
{
   double sum=0;

    for(int i=0;i<5;i++)
        sum+=stduent.grades[i];

    return (sum/5);
}
srilakshmikanthanp
  • 2,231
  • 1
  • 8
  • 25