Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Структуры 
:(
    Опции темы
nastya25
Дата 24.4.2015, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 22.11.2014

Репутация: нет
Всего: нет



Здравствуйте. Помогите понять, в чем ошибка. Программа не выводит нормально средний бал каждого студента по трем предметам и общий средний бал группы.
#include <stdlib.h>
#include <iostream.h>
/*STRUCTURE*/
struct Shop
{
char Name[30];
int Number;
int exam[5];
char Work[5];
char Study[3];
double Sr_ball;
float Sr;
};

void ShowData(Shop *M,int N)
{
system("CLS");
double h;
double *avg=new double[N];
cout<<"Name | Number| exam | Work | Study|    Sr_ball"<<"\n";
for (int i=0;i<N;i++)
{
cout<<M[i].Name;
cout<<" |";
cout<<M[i].Number;
cout<<" |";
cout<<M[i].exam[0]<<" "<<M[i].exam[1]<<" "<<M[i].exam[2]<<" "<<M[i].exam[3]<<" "<<M[i].exam[4];
cout<<" |";
cout<<M[i].Work;
cout<<" | ";
cout<<M[i].Study<<" | ";

for (int i=0; i<5; i++)
{ h=0.;
avg[i]=0;
for (int t=0; t<5; t++)
{

h+=M[i].exam[t];
avg[i]=h/5;
}
cout<<avg[i];
}
cout<<"\n";
}

for (int l=0; l<N; l++)
{
if ((avg[l]>=2) && (avg[l]>=2) && (avg[l]<3))
cout<<"Imeut 2 po examenam: "<<M[i].Name<<" ";
if ((avg[l]>=3) && (avg[l]<4))
cout<<"\n Imeut 3 po examenam: "<<M[i].Name<<" ";
// else cout<<"-";
if ((avg[l]>=4) && (avg[l]<5))
cout<<"\n Imeut 4 po examenam: "<<M[i].Name<<" ";
if (avg[l]>=5)
cout<<"\nImeut 5 po examenam: "<<M[i].Name<<" ";
}

cout<<"\n";
double SR=0;
int k=0;
for(int j=0;j<N;j++)
{
k+=avg[j];
SR= avg[j]/N;
}
cout<<"Srednii ball gruppi: "<<SR<<"\n";

}


/*Zanisit dannie v structure*/
void GetData(Shop *M,int N)
{
cin.ignore();
for (int i=0;i<N;i++)
{
cout<<"n";
cout<<"Name: ";cin.getline(M[i].Name,30);
cout<<"Number: "; cin>>M[i].Number;
cin.ignore();
cout<<"exam: ";
cin>>M[i].exam[0];cin.ignore();
cin>>M[i].exam[1];cin.ignore();
cin>>M[i].exam[2];cin.ignore();
cin>>M[i].exam[3];cin.ignore();
cin>>M[i].exam[4];cin.ignore();
cout<<"Work: ";cin.getline(M[i].Work,5);
cout<<"Study: ";cin.getline(M[i].Study,5);

}
}


void main()
{
system("CLS");
int N; cout<<"Enter N: ";cin>>N;
Shop *M=new Shop[N]; //Динамическое выделение памяти под N структур
GetData(M,N); //Занесение данных в структуры
ShowData(M,N);
delete []M; //Освобождение памяти
system("PAUSE");
}
PM MAIL   Вверх
rudolfninja
Дата 24.4.2015, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Здравствуйте. Что-то очень странное у вас тут просиходит.
Я бы посоветовал вам средний бал студнета считать в методе void GetData(Shop *M,int N) после того, как вы установили все оценки. Тогда в методе ShowData вам надо будет всего лишь вывести на экран значение Sr_ball для каждого элемента входного массива.
Для вывода среднего балла группы просуммируйте средние балы каждого студента и разделите на количество студентов в группе.

Еще пару замечаний по коду: переименуйте структуру, а то она называется Shop, а хранит данные про студента.
В методе void ShowData(Shop *M,int N) вы выделяете память под avg, но не освобождаете ее и получается утечка.
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
double *avg=new double[N];


PM MAIL Skype   Вверх
feodorv
Дата 24.4.2015, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



В программе бардак, конечно. Что бросается в глаза.


Здесь массив из 3-х символов:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
char Study[ 3 ];
А здесь уже предполагается, что он из 5-ти:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
cout<<"Study: ";cin.getline(M[i].Study,5);
Что очень нехорошо...


Опечатка: вместо N стоит 5:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
for (int i=0; i<5; i++)
{ h=0.;
avg[i]=0;
for (int t=0; t<5; t++)



Здесь непонятная целочисленная переменная k. Мало того, что к ней (целочисленной!) прибавляется double-число, так ещё и эта переменная не участвует в формировании результата:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
double SR=0;
int k=0;
for(int j=0;j<N;j++)
{
k+=avg[j];
SR= avg[j]/N;
}



В задании сказано:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
Программа не выводит нормально средний бал каждого студента по трем предметам
, но в программе Вы заложили 5 предметов, это правильно?


В структуре Shop Вы предусмотрели специальное значение для среднего балла:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
double Sr_ball;
Но в программе для этого зачем-то вводите массив avg (который не высвобождаете) и переменную h. Это лишь усложняет и запутывает программу.


Совсем не обязательно вычислять среднее арифметическое внутри цикла:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
for (int t=0; t<5; t++)
{
h+=M[i].exam[t];
avg[i]=h/5;
}
Достаточно в цикле просуммировать, а после разделить на число слагаемых.



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
nastya25
Дата 24.4.2015, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 22.11.2014

Репутация: нет
Всего: нет



Да, прошу прощения. Предметов 5, а не 3. Я исправила и делаю вывод студентов, которые учатся только на "отлично", на "хорошо" и "отлично", у которых есть одна тройка и студентов с  двойками, но результат не совсем верен...(
#include <stdlib.h>
#include <iostream.h>
/*STRUCTURE*/
struct Student
{
 char Name[30];
 int Number;
 int exam[5];
 char Work[5];
 char Study[3];
 //double Sr_ball;
// float Sr;
};

void ShowData(Student *M,int N)
{
 system("CLS");

 cout<<"Name         | Number|      exam |      Work |      Study"<<"\n";
 cout<<"__________________________________________________________\n";
 for (int i=0;i<N;i++)
  {
   cout<<M[i].Name;
   cout<<"     |";
   cout<<M[i].Number;
        cout<<"      |";
   cout<<M[i].exam[0]<<" "<<M[i].exam[1]<<" "<<M[i].exam[2]<<" "<<M[i].exam[3]<<" "<<M[i].exam[4];
            cout<<"  |";
   cout<<M[i].Work;
                   cout<<"        | ";
   cout<<M[i].Study<<"     |  ";


   cout<<"\n";
   }
  }


  void Sr_ball(Student *M,int N )
 {
 double h=0;
double *avg=new double[N];
for (int i=0; i<N; i++)
   { h=0;
   for (int t=0; t<5; t++)
   {
   h+=M[i].exam[t];
  // avg[i]=h/5;
   }
   avg[i]=h/5;
      cout<<"\n Sred:  "<<avg[i];
    }     }

   void Sh(Student *M,int N)
   {
   int k=0;
   int t=0;
   int d=0;
  for (int i=0; i<N; i++)
  {
  for (int j=0; j<5; j++)
 {

  if (M[i].exam[j]==5)
  {
  k=k+1;
  if (k==5)
  cout<<"\nOtlichniki: "<<M[k].Name;
  break;
}
   if (M[i].exam[j]==3)
   {
   t=t+1;
   if (t==1)
   cout<<"\nStudent s  troikami: "<<M[t].Name;
   break;
   }


  if (M[i].exam[j]==2)
   {
   d=d+1;
   if (d>=1)
   cout<<"\nStudent s dvoikami: "<<M[d].Name;
   break;
   }

  if (M[i].exam[j]==4 || M[i].exam[j]==5 || M[i].exam[j]!=2 || M[i].exam[j]!=3)
 {
  cout<<"\nXoroshisti: "<<M[i].Name; }
   break;}
//else cout<<" ";

  }

    }

   void SRR(Student *M,int N)
   {
   double *avg=new double[N];
  double SR=0;

  for(int j=0;j<N;j++)

  {
  int k=0;
  k+=avg[j];

  }
  SR= avg[j]/N;
  cout<<"\nSrednii ball gruppi: "<<SR<<"\n";

 }


/*Zanisit dannie v structure*/
void GetData(Student *M,int N)
{
 cin.ignore();
 for (int i=0;i<N;i++)
  {
   cout<<"n";
   cout<<"Name: ";cin.getline(M[i].Name,30);
   cout<<"Number:  ";   cin>>M[i].Number;
   cin.ignore();
   cout<<"exam: ";
   cin>>M[i].exam[0];cin.ignore();
   cin>>M[i].exam[1];cin.ignore();
   cin>>M[i].exam[2];cin.ignore();
   cin>>M[i].exam[3];cin.ignore();
   cin>>M[i].exam[4];cin.ignore();
   cout<<"Work: ";cin.getline(M[i].Work,5);
   cout<<"Study: ";cin.getline(M[i].Study,5);

}
}


void main()
{
 system("CLS");
    int N; cout<<"Enter  N: ";cin>>N;
    Student *M=new Student[N]; //Динамическое выделение памяти под N структур
       GetData(M,N); //Занесение данных в структуры
       ShowData(M,N);
       Sr_ball(M,N);
       SRR(M,N);
       Sh(M,N);
    delete []M; //Освобождение памяти
 system("PAUSE");
 }
PM MAIL   Вверх
rudolfninja
Дата 24.4.2015, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Настя, ваш код очень трудно читать. Пожалуйста, отформатируйте его и используйте тег для подсветки кода.
Расскажите, вообще, как звучит полное задание? Давайте попробуем вместе написать его заново?
PM MAIL Skype   Вверх
nastya25
Дата 24.4.2015, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 22.11.2014

Репутация: нет
Всего: нет



Извиняюсь. Нужно обработать результаты сессии. в переменной exam хранятся оценки за сессию каждого студента. В процедуре Sh выводятся фамилии студентов, которые сдали сессию на "отлично", на "хорошо" и "отлично", имеют одну тройку и имеют двойки. Я это пытаюсь сделать..но результаты немного неоднозначны..
Код

#include <stdlib.h>
#include <iostream.h>
/*STRUCTURE*/
struct Student
{
 char Name[30];
 int Number;
 int exam[5];
 char Work[5];
 char Study[3];
};

void ShowData(Student *M,int N)
{
 system("CLS");

 cout<<"Name         | Number|      exam |      Work |      Study"<<"\n";
 cout<<"__________________________________________________________\n";
 for (int i=0;i<N;i++)
  {
   cout<<M[i].Name;
   cout<<"     |";
   cout<<M[i].Number;
        cout<<"      |";
   cout<<M[i].exam[0]<<" "<<M[i].exam[1]<<" "<<M[i].exam[2]<<" "<<M[i].exam[3]<<" "<<M[i].exam[4];
            cout<<"  |";
   cout<<M[i].Work;
                   cout<<"        | ";
   cout<<M[i].Study<<"     |  ";


   cout<<"\n";
   }
  }


  void Sr_ball(Student *M,int N )
 {
 double h=0; double p,l;
double *avg=new double[N];
for (int i=0; i<N; i++)
   { h=0; //p=0;l=0;
   for (int t=0; t<5; t++)
   {
   h+=M[i].exam[t];
   }
   avg[i]=h/5;
      cout<<"\n Sred:  "<<avg[i];
      p+=avg[i];
    }
    l=p/N;
    cout<<"\n Srednii ball gruppi: "<<l;
    }

   void Sh(Student *M,int N)
   {
   int k=0;
   int t=0;
   int d=0;
  for (int i=0; i<N; i++)
  {
  for (int j=0; j<5; j++)
 {
   k=0; t=0; d=0;

  if (M[i].exam[j]==2)
   {
   d=d+1;
   if (d>=1)
   cout<<"\nStudent s dvoikami: "<<M[i].Name;
   break;
   }

   if (M[i].exam[j]==3)
   {
   t=t+1;
   if (t==1)
   cout<<"\nStudent s  troikami: "<<M[i].Name;
   break;
   }

  if (M[i].exam[j]==4 ||M[i].exam[j]==5 || M[i].exam[j]!=2 || M[i].exam[j]!=3)
 {
  cout<<"\nXoroshisti: "<<M[i].Name; }
  break;
 }
//else cout<<" ";

if (M[i].exam[j]==5 || M[i].exam[j]!=4 || M[i].exam[j]!=3 || M[i].exam[j]!=2)
  {
  cout<<"\nOtlichniki: "<<M[i].Name;
  break;
  }
  }
    }


/*Zanisit dannie v structure*/
void GetData(Student *M,int N)
{
 cin.ignore();
 for (int i=0;i<N;i++)
  {
   cout<<"n";
   cout<<"Name: ";cin.getline(M[i].Name,30);
   cout<<"Number:  ";   cin>>M[i].Number;
   cin.ignore();
   cout<<"exam: ";
   cin>>M[i].exam[0];cin.ignore();
   cin>>M[i].exam[1];cin.ignore();
   cin>>M[i].exam[2];cin.ignore();
   cin>>M[i].exam[3];cin.ignore();
   cin>>M[i].exam[4];cin.ignore();
   cout<<"Work: ";cin.getline(M[i].Work,5);
   cout<<"Study: ";cin.getline(M[i].Study,5);

}
}


void main()
{
 system("CLS");
    int N; cout<<"Enter  N: ";cin>>N;
    Student *M=new Student[N]; //Динамическое выделение памяти под N структур
       GetData(M,N); //Занесение данных в структуры
       ShowData(M,N);
       Sr_ball(M,N);
       Sh(M,N);
    delete []M; //Освобождение памяти
 system("PAUSE");
 }

PM MAIL   Вверх
rudolfninja
Дата 25.4.2015, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Вы как-то странно считаете средний балл.
Почему бы не считать средний балл в функции, где вы вводите данные?

Код


/*STRUCTURE*/
struct Student
{
 char Name[30];
 int Number;
 int exam[5];
 char Work[5];
 char Study[3];
 double av_mark;
};

/*Zanisit dannie v structure*/
void GetData(Student *M,int N)
{
 cin.ignore();
 for (int i=0;i<N;i++)
  {
   cout<<"n";
   cout<<"Name: ";
   cin.getline(M[i].Name,30);
   cout<<"Number:  ";  
   cin>>M[i].Number;
   cin.ignore();
   cout<<"exam: ";
   cin>>M[i].exam[0];cin.ignore();
   cin>>M[i].exam[1];cin.ignore();
   cin>>M[i].exam[2];cin.ignore();
   cin>>M[i].exam[3];cin.ignore();
   cin>>M[i].exam[4];cin.ignore();
   cout<<"Work: ";
   cin.getline(M[i].Work,5);
   cout<<"Study: ";
   cin.getline(M[i].Study,5);

   double sum = 0;
   for(int j = 0; j < 5; j++)
       sum += M[i].exam[j];

   M[i].av_mark = sum / 5;
}


После этого у вас будет храниться средний балл в объекте вашей структуры.
Отличники - те, у кого средний бал равен 5.
Отличники и хорошисты - больше 4, но меньше 5.
Ну тройки и двойки тоже просто найти.

PM MAIL Skype   Вверх
nastya25
Дата 25.4.2015, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 22.11.2014

Репутация: нет
Всего: нет



Если у человека по 4-м предметам стоит оценка "5", а по одному -"3", то средний балл за 5 экзаменов - 4.6 , но не хорошист.. Поэтому я решила считать , исходя из оценок.
PM MAIL   Вверх
rudolfninja
Дата 25.4.2015, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 341
Регистрация: 19.2.2013
Где: г. Минск

Репутация: 1
Всего: 6



Да, все верно.
Тогда, примерно так будет:
Код

for(int i = 0; i < N; i++)
{
// находим отличников
if(student[i].av_mark == 5.0)
{
std::cout << student[i].Name << " отличник" << std::endl;
continue;
}

// находим хорошистов
bool is_good = true;
for(int j = 0; j < 5; j++)
{
if(student[i].exam[j] < 4)
{
is_good = false;
break;
}
}
if(is_good)
{
std::cout << student[i].Name << " хорошист" << std::endl;
continue;
}

// ищем троечников
is_good = true;
for(int j = 0; j < 5; j++)
{
if(student[i].exam[j] == 3)
{
is_good = false;
break;
}
}
if(!is_good)
{
std::cout << student[i].Name << " троечник" << std::endl;
continue;
}

std::cout << student[i].Name << " двоечник" << std::endl;

}


Вот. Я не уверен, но должно сработать. Код не проверял, писал сразу тут, но логика правильная должна быть.
Поскольку на часах без пятнадцати два ночи, то могут присутствовать некоторые ошибки. Если таковые есть - приношу извинения.
PM MAIL Skype   Вверх
feodorv
Дата 25.4.2015, 06:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 12
Всего: 45



Цитата(nastya25 @  24.4.2015,  23:25 Найти цитируемый пост)
но результаты немного неоднозначны..

Просто надо все правильно сделать. У Вс есть цикл по студентам, в него вложен цикл по оценкам:
Цитата(nastya25 @  24.4.2015,  23:25 Найти цитируемый пост)
   int k=0;
   int t=0;
   int d=0;
  for (int i=0; i<N; i++)
  {
  for (int j=0; j<5; j++)
 {
   k=0; t=0; d=0;

Здесь мы видим неуместную инициализацию переменных. Они должны быть инициализированы (нулями) перед циклом по оценкам, а не внутри него. Идея с подсчетом оценок мне нравиться, только реализована она неверно:
Код

for (int i=0; i<N; i++)
{
  int o5 = 0, o4 = 0, o3 = 0, o2 = 0;

  for (int j=0; j<5; j++)
  {
    if( M[i].exam[j] == 5 )
      o5++;
    else if( M[i].exam[j] == 4 )
      o4++;
    else if( M[i].exam[j] == 3 )
      o3++;
    else
      o2++;
  }

  // Здесь принятие решения о том, отличник ли студент, хорошист и так далее
}



Как видите, принятие решения о статусе студента происходит по окончании цикла по ошибкам, а не внутри него!!!
Код

  if( o2 != 0 )
    cout<<"Student s dvoikami: "<<M[i].Name << endl;
  else if( o3 != 0 )
    cout<<"Student s troikami: "<<M[i].Name << endl;
  else if( o4 != 0 )
    cout<<"Xoroshist: "<<M[i].Name << endl;
  else
    cout<<"Otlichnik: "<<M[i].Name << endl;



Эти условия безумны:
Цитата(nastya25 @  24.4.2015,  23:25 Найти цитируемый пост)
  if (M[i].exam[j]==4 ||M[i].exam[j]==5 || M[i].exam[j]!=2 || M[i].exam[j]!=3)

Цитата(nastya25 @  24.4.2015,  23:25 Найти цитируемый пост)
if (M[i].exam[j]==5 || M[i].exam[j]!=4 || M[i].exam[j]!=3 || M[i].exam[j]!=2)

Эти условия выполняются при любом значении M[i].exam[j], смысла в этом мало.


Это проигнорировано всеми:
Цитата(feodorv @  24.4.2015,  13:15 Найти цитируемый пост)
Здесь массив из 3-х символов:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
char Study[ 3 ];
А здесь уже предполагается, что он из 5-ти:
Цитата(nastya25 @  24.4.2015,  12:34 Найти цитируемый пост)
cout<<"Study: ";cin.getline(M[i].Study,5);
Что очень нехорошо...

Именно поэтому в таких выражениях лучше использовать оператор sizeof:
Код

cin.getline( M[i].Study, sizeof(M[i].Study));

Меньше головной боли, однозначно.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1611 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.