Структура "Студент", вывод фамилий и номеров групп студентов имеющих положительные оценки
Изучаю самостоятельно С++. Добрался до ООП. Решаю задачи. А именно: "Создайте структуру с именем student, содержащую поля: фамилия и инициалы, номер группы, успеваемость (массив из пяти элементов). Создать массив из десяти элементов такого типа, упорядочить записи по возрастанию среднего балла. Добавить возможность вывода фамилий и номеров групп студентов, имеющих оценки, равные только 4 или 5."
Немного модифицировал задание, создав класс. И добавив динамическое выделение памяти, чтобы потренироваться. Буду благодарен за проверку. А вообще хочу получить рекомендации "Как сделать лучше", "Что требуется поменять", "Что и почему лучше использовать", "Как делать нельзя".
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
/*
1. Создайте структуру с именем student, содержащую поля: фамилия и инициалы, номер группы, успеваемость (массив из пяти элементов).
Создать массив из десяти элементов такого типа, упорядочить записи по возрастанию среднего балла.
Добавить возможность вывода фамилий и номеров групп студентов, имеющих оценки, равные только 4 или 5.
*/
class Student
{
public:
Student()
{
/* string str;
cout << "Фамилия студента: "; cin >> str;
this->sirname = str;
cout << "Инициалы: "; cin >> str;
this->inicial = str;*/
sirname = "";
inicial = "";
number = 0;
/*while (true)
{
int num;
cout << "Номер группы: "; cin >> num;
if (cin.fail())
{
cin.clear();
cin.ignore(32767, '\n');
cout << "Неверный номер группы! Введите корректно!\n";
}
else
{
cin.ignore(32767, '\n');
this->number = num;
break;
}
}*/
/* while (true)
{
int num;
_flushall();
rewind(stdin);
printf_s("Номер группы: "); scanf_s("%d", &num);
if (getchar() != '\n'&& getchar() != EOF || num < 1000 || num >9999)
{
printf_s("Неверный номер группы! Введите корректно!\n");
}
else
{
this->number = num;
break;
}
}*/
for (int i = 0; i < n; i++)
{
int inputData = rand() % 4 + 2;
this->uspev[i] = inputData;
}
}
Student(string sirname, string inicial, int number) :Student()
{
this->sirname = sirname;
this->inicial = inicial;
this->number = number;
}
Student(string sirname, string inicial, int number, int *uspev) :Student(sirname, inicial, number)
{
for (int i = 0; i < 5; i++)
{
this->uspev[i] = uspev[i];
}
}
~Student()
{
//cout << "\nВызван деструктор " << this << endl;
if (uspev != nullptr)
{
delete[] uspev;
}
//cout << "Данные удалены" << endl;
}
/* Конструктор копирования */
Student(const Student ©Object)
{
this->sirname = copyObject.sirname;
this->inicial = copyObject.inicial;
this->number = copyObject.number;
this->uspev = new int[copyObject.n];
for (int i = 0; i < copyObject.n; i++)
{
this->uspev[i] = copyObject.uspev[i];
}
}
void PrintStud()
{
cout << "Фамилия студента: " + sirname << endl;
cout << "Инициалы студента: " + inicial << endl;
cout << "Номер группы: ПАО_" << number << endl;
cout << "Оценки студента: ";
for (int i = 0; i < this->n; i++)
{
cout << this->uspev[i] << " ";
}
cout << "\nСредний балл студента: " << SrBal() << endl;
}
void SetStud(string sirname, string inicial, int number)
{
this->sirname = sirname;
this->inicial = inicial;
this->number = number;
}
double SrBal()
{
double srBal = 0.0;
for (int i = 0; i < n; i++)
{
srBal += uspev[i];
}
return srBal / n;
}
/* Перегрузка оператора присваивания */
Student& operator = (const Student & other)
{
if (this->uspev != nullptr)
{
delete[] this->uspev;
}
this->sirname = other.sirname;
this->inicial = other.inicial;
this->number = other.number;
this->uspev = new int[other.n];
for (int i = 0; i < other.n; i++)
{
this->uspev[i] = other.uspev[i];
}
return *this;
}
/* Перегрузки операторов сравнения */
bool operator ==(const Student &other)
{
return this->sirname == other.sirname&&this->inicial == other.inicial&&this->number == other.number&&this->uspev == other.uspev;
}
bool operator !=(const Student &other)
{
return !(this->sirname == other.sirname&&this->inicial == other.inicial&&this->number == other.number&&this->uspev == other.uspev);
}
bool operator >(const Student &other)
{
return this->sirname > other.sirname&&this->inicial > other.inicial&&this->number > other.number&&this->uspev > other.uspev;
}
bool operator >=(const Student &other)
{
return this->sirname >= other.sirname&&this->inicial >= other.inicial&&this->number >= other.number&&this->uspev >= other.uspev;
}
bool operator <(const Student &other)
{
return this->sirname < other.sirname&&this->inicial < other.inicial&&this->number < other.number&&this->uspev < other.uspev;
}
bool operator <=(const Student &other)
{
return this->sirname <= other.sirname&&this->inicial <= other.inicial&&this->number <= other.number&&this->uspev <= other.uspev;
}
int & operator [](int index)
{
return uspev[index];
}
bool CheckFourOrFive()
{
int count = 0;
for (int i = 0; i < n; i++)
{
if (uspev[i] < 4)
{
count++;
}
}
if (count == 0)
{
return true;
}
else
{
return false;
}
}
private:
const int n = 5;
string sirname;
string inicial;
int number;
int *uspev = new int[n];
};
void SortSrBal(Student *st, const int size)
{
Student temp;
// Сортировка массива пузырьком
for (int i = 0; i < size - 1; i++)
{
for (int j = 0; j < size - i - 1; j++)
{
if (st[j].SrBal() > st[j + 1].SrBal())
{
temp = st[j];
st[j] = st[j + 1];
st[j + 1] = temp;
}
}
}
}
void OutputFourOrFive(Student *st, const int size)
{
int count = 0;
for (int i = 0; i < size; i++)
{
if (st[i].CheckFourOrFive())
{
st[i].PrintStud();
cout << endl;
count++;
}
}
if (count == 0)
{
cout << "Нет студентов с оценками 4 и 5 !!!" << endl;
}
}
int main()
{
setlocale(LC_ALL, "");
srand(time(NULL));
const int N = 5;
Student *STUD = new Student[N];
system("cls");
STUD[0].SetStud("Зажорин", "С.А.", 1398);
STUD[1].SetStud("Иванов", "И.И.", 4417);
STUD[2].SetStud("Петров", "В.П.", 2341);
STUD[3].SetStud("Сидоров", "И.З.", 6715);
STUD[4].SetStud("Кочкин", "Л.П.", 4567);
for (int i = 0; i < N; i++)
{
STUD[i].PrintStud();
cout << endl;
}
cout << "================================================================\n";
cout << "================================================================\n\n";
cout << "Сортировка хлопчиков по возрастанию(средний балл)_:\n\n";
SortSrBal(STUD, N);
for (int i = 0; i < N; i++)
{
STUD[i].PrintStud();
cout << endl;
}
cout << "================================================================\n";
cout << "================================================================\n\n";
cout << "Вывод студентов \"только\" с оценками 4 и 5_:\n\n";
OutputFourOrFive(STUD, N);
delete[] STUD;
return 0;
}
С уважением.
Дополнено. Отредактировал. Прошу проверить и дать советы)
#include <iostream>
#include <string>
#include <ctime>
#include <conio.h>
#include <Windows.h>
#include <array>
#include <vector>
using namespace std;
void StartInputConsole();
void EndInputConsole();
/*
1. Создайте структуру с именем student, содержащую поля: фамилия и инициалы, номер группы, успеваемость (массив из пяти элементов).
Создать массив из десяти элементов такого типа, упорядочить записи по возрастанию среднего балла.
Добавить возможность вывода фамилий и номеров групп студентов, имеющих оценки, равные только 4 или 5.
*/
class Student
{
public:
Student()
{
sirname = "";
inicial = "";
number = 0;
cout << "Введите фамилию студента: ";
StartInputConsole();
getline(cin, sirname);
EndInputConsole();
cout << "Введите инициалы студента: ";
StartInputConsole();
getline(cin, inicial);
EndInputConsole();
cout << "Введите номер группы(4 цифры): ";
cin >> number;
cin.ignore(32767, '\n');
for (int i = 0; i < n; i++)
{
int inputData = rand() % 4 + 2;
this->uspev.at(i) = inputData;
}
}
Student(string sirname, string inicial, int number) /* :Student()*/
{
this->sirname = sirname;
this->inicial = inicial;
this->number = number;
for (int i = 0; i < n; i++)
{
int inputData = rand() % 4 + 2;
this->uspev.at(i) = inputData;
}
}
Student(string sirname, string inicial, int number, array<int, 5> &uspev) :Student(sirname, inicial, number)
{
for (int i = 0; i < 5; i++)
{
this->uspev.at(i) = uspev.at(i);
}
}
~Student()
{
}
/* Конструктор копирования */
Student(const Student ©Object)
{
this->sirname = copyObject.sirname;
this->inicial = copyObject.inicial;
this->number = copyObject.number;
this->uspev = copyObject.uspev;
for (int i = 0; i < copyObject.n; i++)
{
this->uspev.at(i) = copyObject.uspev.at(i);
}
}
void PrintStud()
{
cout << "Фамилия студента: " + sirname << endl;
cout << "Инициалы студента: " + inicial << endl;
cout << "Номер группы: ПАО_" << number << endl;
cout << "Оценки студента: ";
for (int i = 0; i < n; i++)
{
cout << this->uspev.at(i) << " ";
}
cout << "\nСредний балл студента: " << SrBal() << endl;
}
void SetStud(string sirname, string inicial, int number)
{
this->sirname = sirname;
this->inicial = inicial;
this->number = number;
}
double SrBal()
{
double srBal = 0.0;
for (int i = 0; i < n; i++)
{
srBal += uspev.at(i);
}
return srBal / n;
}
/* Перегрузка оператора присваивания */
Student& operator = (const Student & other)
{
this->sirname = other.sirname;
this->inicial = other.inicial;
this->number = other.number;
this->uspev = other.uspev;
for (int i = 0; i < other.n; i++)
{
this->uspev.at(i) = other.uspev.at(i);
}
return *this;
}
///* Перегрузки операторов сравнения */
//bool operator ==(const Student &other)
//{
// return this->sirname == other.sirname&&this->inicial == other.inicial&&this->number == other.number&&this->uspev == other.uspev;
//}
//bool operator !=(const Student &other)
//{
// return !(this->sirname == other.sirname&&this->inicial == other.inicial&&this->number == other.number&&this->uspev == other.uspev);
//}
//bool operator >(const Student &other)
//{
// return this->sirname > other.sirname&&this->inicial > other.inicial&&this->number > other.number&&this->uspev > other.uspev;
//}
//bool operator >=(const Student &other)
//{
// return this->sirname >= other.sirname&&this->inicial >= other.inicial&&this->number >= other.number&&this->uspev >= other.uspev;
//}
//bool operator <(const Student &other)
//{
// return this->sirname < other.sirname&&this->inicial < other.inicial&&this->number < other.number&&this->uspev < other.uspev;
//}
//bool operator <=(const Student &other)
//{
// return this->sirname <= other.sirname&&this->inicial <= other.inicial&&this->number <= other.number&&this->uspev <= other.uspev;
//}
/*int & operator [](int index)
{
return uspev[index];
}*/
bool CheckFourOrFive()
{
int count = 0;
for (int i = 0; i < n; i++)
{
if (uspev.at(i) < 4)
{
count++;
}
}
return count == 0;
}
private:
static const int n = 5;
string sirname;
string inicial;
int number;
array<int, n> uspev;
};
void SortSrBal(vector<Student> &st)
{
sort(st.begin(), st.end(), [](Student& a, Student& b) { return a.SrBal() < b.SrBal(); });
}
void OutputFourOrFive(vector<Student> &st)
{
int count = 0;
for (int i = 0; i < st.size(); i++)
{
if (st[i].CheckFourOrFive())
{
st[i].PrintStud();
cout << endl;
count++;
}
}
if (count == 0)
{
cout << "Нет студентов с оценками 4 и 5 !!!" << endl;
}
}
int main()
{
setlocale(LC_ALL, "");
srand(time(NULL));
const int N = 5;
vector<Student> STUD;
array<int, N> arr{ 5, 4, 5, 4, 5 };
STUD.push_back(Student("Зажорин", "С.А.", 1398));
STUD.push_back(Student("Иванов", "И.И.", 4417));
STUD.push_back(Student("Петров", "В.П.", 2341, arr));
STUD.push_back(Student("Сидоров", "И.З.", 6715));
STUD.push_back(Student("Кочкин", "Л.П.", 4567));
STUD.push_back(Student());
system("cls");
for (int i = 0; i < STUD.size(); i++)
{
STUD.at(i).PrintStud();
cout << endl;
}
cout << "================================================================\n";
cout << "================================================================\n\n";
cout << "Сортировка хлопчиков по возрастанию(средний балл)_:\n\n";
SortSrBal(STUD);
for (int i = 0; i < STUD.size(); i++)
{
STUD.at(i).PrintStud();
cout << endl;
}
cout << "================================================================\n";
cout << "================================================================\n\n";
cout << "Вывод студентов \"только\" с оценками 4 и 5_:\n\n";
OutputFourOrFive(STUD);
_getch();
return 0;
}
// Функции:
void StartInputConsole()
{
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
}
void EndInputConsole()
{
SetConsoleCP(866);
SetConsoleOutputCP(866);
}
Ответы (1 шт):
ну как минимум не нужно делать int *uspev = new int[n];. Если размер фиксирован - используйте просто массив/std::array, если размер может меняться - std::vector. Это очень сильно упростит код. Даже позволит отказаться от самописных конструкторов копирования.
if (count == 0)
{
return true;
}
else
{
return false;
}
это можно в одну строку
return count == 0;
SortSrBal - а может в ней использовать стандартную std::sort?
операторы сравнения... тут явно с пробелами нужно поработать. А потом стает понятно одно - они неверны. У Вас требуется, что бы все переменные были "одного знака". А что делать с теми случаями, когда это не выполняется? то есть, у Вас может быть, что a > b и a < b будет одновременно false, и при этом a != b. Это обычно приводит к плохой сортировке.
вот такая конструкция не имеет смысла
if (uspev != nullptr)
{
delete[] uspev;
}
delete умеет работать с nullptr самостоятельно.
многие куски кода можно упростить, если использовать алгоритмы стандартной библиотеки. Но, возможно, это запрещено под страхом сильных наказаний.