Описать структуру с именем STUDENT, содержащую следующие поля:
- фамилия и инициалы;
- номер зачетной книжки;
- факультет (тип – перечисление);
- номер группы;
- адрес;
- успеваемость (массив из пяти элементов).
Написать программу, выполняющую следующие действия:
-инициализацию данных в массив, состоящий из 12 структур типа STUDENT;
- сортировку записей по факультетам;
- сортировку по группам;
- формирование нового массива – отличников;
- удаление из исходного массива двоечников;
- вывод студентов, имеющих оценки 3 и 4.
Если таких элементов нет, вывести соответствующее сообщение
namespace з3
{
enum facultet:byte
{
ФАЭМ,
РТФ,
ЕГФ,
АФ,
ИЭФ
}
struct student
{
public string fio;
public int nomZach;
public facultet fac;
public string nomGr;
public string adres;
public int[] usp;
}
class Class1
{
static void Init (out student stud) //Создание
{
Console.WriteLine("Введите фамилию, имя и отчество студента");
stud.fio=Console.ReadLine();
Console.WriteLine("Введите номер зачетки ");
stud.nomZach=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Выберите факультет");
Console.WriteLine("0 - ФАЭМ"+"\n"+"1 - РТФ"+"\n"+ "2 - ЕГФ"+"\n"+"3 - АФ"+"\n"+"4 - ИЭФ");
stud.fac=(facultet)Convert.ToByte(Console.ReadLine());
Console.WriteLine("Введите номер группы");
stud.nomGr=Console.ReadLine();
Console.WriteLine("Введите адрес");
stud.adres=Console.ReadLine();
int[] oc=new int [5];
Console.WriteLine("Введите успеваемость");
for (int j=0; j<5; j++)
{
oc[j]=Convert.ToInt32(Console.ReadLine());
}
stud.usp=oc;
}
//Создание по умолчанию
static void DefInit(out student stud, string f, string nG, string ad, int nZ, byte facul,int[] oc)
{
stud.fio = f;
stud.nomZach = nZ;
stud.fac = (facultet)facul;
stud.nomGr = nG;
stud.adres = ad;
stud.usp = oc;
}
static void DefaultZap(params student[] stud)
{
nt[] oc ={ 5, 5, 5, 5, 5 };
DefInit(out stud[0],"Кипелов Валерий Александрович", "ВМ-081","",1801,0,oc);
int[] oc0 ={ 5, 3, 5, 4, 5 };
DefInit(out stud[1], "Холстинин Владимир Сергеевич", "ИС-081", "", 1832, 2, oc0);
int[] oc1 ={ 2, 5, 3, 4, 4 };
DefInit(out stud[2], "Дубинин Виталий Андреевич", "РД-081", "", 1816, 3, oc1);
int[] oc2 ={ 3, 4, 4, 3, 3 };
DefInit(out stud[3], "Жмельков Олег Григорьевич", "РК-081", "", 1803, 1, oc2);
int[] oc3 ={ 3, 2, 5, 4, 5 };
DefInit(out stud[4], "Немоляев Кирилл Петрович", "ПТ-081", "", 1808, 3, oc3);
int[] oc4 ={ 5, 5, 5, 5, 5 };
DefInit(out stud[5], "Маврин Сергей Викторович", "ВМ-081", "", 1817, 0, oc4);
int[] oc5 ={ 5, 4, 4, 5, 5 };
DefInit(out stud[6], "Горшенев Михаил Валерьевич", "АТ-081", "", 1884, 0, oc5);
int[] oc6={ 2, 2, 3, 2, 3 };
DefInit(out stud[7], "Лобашев Андрей Евгеньевич", "ЭК-081", "", 1811, 4, oc6);
int[] oc7={ 5, 5, 5, 5, 5 };
DefInit(out stud[8], "Грановский Алик Дмитриевич", "ВМ-081", "", 1899, 0, oc7);
int[] oc8={ 4, 4, 4, 2, 4 };
DefInit(out stud[9], "Михеев Артур Степанович ", "ИС-081", "", 1873, 2, oc8);
int[] oc9={ 4, 3, 3, 3, 3 };
DefInit(out stud[10], "Нефедова Мария Сергеевна", "ЭСХ-081", "", 1876, 0, oc9);
int[] oc10={ 5, 5, 3, 3, 3 };
DefInit(out stud[11], "Булгаков Алексей Владимирович", "РТ-081", "", 1809, 1, oc10);
}
static void Print (student stud) //Печать
{
Console.WriteLine("\n"+stud.fio+"\t"+stud.nomZach+"\t"+
stud.nomGr+"\t"+stud.fac);
Console.WriteLine("Адрес: "+stud.adres);
Console.Write("Успеваемость: ");
foreach (int a in stud.usp) Console.Write("\t"+a);
Console.WriteLine();
}
static void SortGr(student[] A) //Сортировка по группам
{
student[] B = A;
for (int i=0; i<B.Length; i++)
{
for (int j=i; j<B.Length; j++)
{
If (A[j].nomGr.CompareTo(B[i].nomGr) < 0)
{
student h;
h=B[i];
B[i]=B[j];
B[j]=h;
}
}
}
foreach (student a in B) Print(a);
}
static void SortF(student[] A) //Сортировка по факультетам
{
student[] B = A;
for (int i = 0; i < B.Length; i++)
{
for (int j = i; j < B.Length; j++)
{
if(Convert.ToString(B[j].fac).CompareTo(Convert.ToString(B[i].fac)) < 0)
{
student h;
h = B[i];
B[i] = B[j];
B[j] = h;
}
}
}
foreach (student a in B) Print(a);
}
static void FindOtl(student[] A) //Поиск отличников
{
int n = 0;
student[] B = new student[A.Length];
for (int i = 0; i < A.Length; i++)
{
bool flag = true;
for (int j = 0; j < 5; j++)
{
if (A[i].usp[j].CompareTo(5) != 0)
{
flag = false;
break;
}
}
if (flag)
{
B[n] = A[i];
n++;
}
}
for (int i = 0; i < n; i++)
Print(B[i]);
}
static void FindDv(student[] A, out int n) //Удаление двоечников
{
student[] B = A;
n=0;
for (int i = 0; i < A.Length; i++)
{
bool flag = true;
for (int j = 0; j < A[i].usp.Length; j++)
{
if (A[i].usp[j] == 2)
{
flag = false;
break;
}
}
if (flag==true)
{
B[n] = A[i];
n++;
}
}
for (int i = 0; i < n; i++)
A[i] = B[i];
for (int i = 0; i < n; i++ ) Print(A[i]);
}
static void Poisk(student[] A, int n) //Вывод троечников и хорошистов
{
for (int i = 0; i < n; i++)
{
bool flag = true;
for (int j = 0; j < 5; j++)
{
if ((A[i].usp[j].CompareTo(3) != 0) && (A[i].usp[j].CompareTo(4) != 0))
{
flag = false;
break;
}
}
if (flag) Print(A[i]);
}
}
static void Main(string[] args)
{
Console.WriteLine("Нажмите Enter для просмотра записей"+"\n");
student[] st=new student[12];
int newRazm;
DefaultZap(st);
Console.ReadLine();
foreach (student a in st) Print(a);
Console.WriteLine("\n"+
"Enter для просмотра списка, отсортированного по номеру группы"+"\n");
Console.ReadLine();
SortGr(st);
Console.WriteLine("\n" +
"Нажмите Enter для просмотра списка, отсортированного по факультетам" + "\n");
Console.ReadLine();
SortF(st);
Console.WriteLine();
Console.WriteLine("\n" + "Нажмите Enter для просмотра списка отличников" + "\n");
Console.ReadLine();
FindOtl(st);
Console.WriteLine("\n" +
"Нажмите Enter для удаления двоечников из списка" + "\n");
Console.ReadLine();
FindDv(st,out newRazm);
Console.WriteLine("\n"+
"Нажмите Enter для просмотра записей о студентах, учащихся на 3 и 4" + "\n");
Console.ReadLine();
Poisk(st,newRazm);
}
}
}
Цель работы: приобретение навыков обработки символов, строк, массивов символов.
Переменная типа string – это массив переменных типа char, доступных в режиме «только чтение». Получить доступ к отдельным символам можно так
string myString = "Строка";
char myChar = myString[0];
Для получения массива, доступного для записи, пользуются методом ToCharArray()
string myString = "Строка";
char[] myChars = myString.ToCharArray();
// также можно использовать оператор foreach
foreach( char c in myString)
{
Console.WriteLine("{0}", c);
}
string - это ссылочный тип, и в результате присваивания создается ссылка на константную строку, хранимую в «куче».
С одной и той же строковой константой в «куче» может быть связано несколько переменных строкового типа. Но эти переменные не являются разными именами одного объекта.
Строковые константы в «куче» не изменяются, поэтому, когда одна из переменных получает новое значение, она связывается с новым константным объектом в «куче». Это означает, что семантика присваивания строк аналогична семантике значимого присваивания.
Операции сравнения строк сравнивают их значения, а не ссылки. Эти операции выполняются как над значимыми типами.
Бинарная операция "+" сцепляет две строки, приписывая вторую строку к хвосту первой.
Возможность взятия индекса при работе со строками отражает факт, что строку можно рассматривать как массив и получать каждый ее символ.
Каждый символ строки имеет тип char, доступный только для чтения, но не для записи.
Пример, в котором над строками выполняются данные операции:
static void TestOpers()
{
//операции над строками
string s1 ="ABC", s2 ="CDE";
string s3 = s1+s2;
bool b1 = (s1==s2);
char ch1 = s1[0], ch2=s2[0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," +
"ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);
s2 = s1;
b1 = (s1!=s2);
ch2 = s2[0];
Console.WriteLine("s1={0}, s2={1}, b1={2}," +
"ch1={3}, ch2={4}", s1,s2,b1,ch1,ch2);
//Неизменяемые значения
s1= "Zenon";
// s1[0]='L'; приведет к ошибке
}
Рис. 24. Операции со строками
В языке C# указатели допускаются в блоках, отмеченных как небезопасные. В таких блоках можно объявить переменную типа char*, но программа, такая же изящная, как в С++, не получится.
Рассмотрим базовый класс для символов. Тип char, как и другие типы C#, является классом. Этот класс наследует свойства и методы класса Object и имеет собственные методы.
Символьный класс Char, основанный на классе System.Char, использует 2 байта для кодирования символа (таблица Unicode).
Символьный литерал, как и в С++, заключается в апострофы. Примеры работы с символьными переменными:
static void TestChar()
{
char ch1='A', ch2 ='\x5A', ch3='\u0058';
char ch = new Char();
int code; string s;
ch = ch1;
//преобразование символьного и int типов
code = ch; ch1=(char) (code +1);
//преобразование символьного типа в строку
//s = ch; конечно, недопустимо
s = ch1.ToString()+ch2.ToString()+ch3.ToString();
Console.WriteLine("s= {0}, ch= {1}, code = {2}", s, ch, code);
}
Три символьные переменные инициализированы константами, значения которых заданы тремя разными способами. Переменная ch объявляется в объектном стиле, используя new и вызов конструктора класса.
Явные или неявные преобразования между классами Char и String отсутствуют, но есть метод ToString() для перевода символа в строку.
Преобразование целочисленных типов в тип char следует задать явно.
Функция TestChar() формирует строку s путем сцепления трех символов, преобразованных в строки. Значение s равно «BZX», при этом ch=А, а ее код - code = 65.
Примеры преобразования символа в его код и обратно:
static int SayCode(char sym)
{ return (sym); }
static char SaySym(object code)
{ return ((char)((int)code)); }
static void Main(string[] args)
{
char ch1 = 'A';
Console.WriteLine("ch1={0}, Unicode({1})={2}",
ch1, SaySym(SayCode(ch1)), SayCode(ch1));
}
В первой функции приведение к целому типу выполняется неявно.
Во второй - преобразование явное. Ее формальный параметр имеет тип object, за счет чего она вызывается с параметром, заданным любым целочисленным типом. Но позже придется выполнить явные преобразования.
Статические методы и свойства класса Char представлены в табл. 7. Большинство статических методов перегружены. Они могут применяться как к отдельному символу, так и к строке, для которой указывается номер символа. Основную группу составляют методы Is, полезные при разборе строки. Примеры методов:
static void TestCharMethods()
{
Console.WriteLine("Статические методы класса char:");
char ch='a', ch1='1', lim =';', chc='\xA';
double d1, d2;
d1=char.GetNumericValue(ch); d2=char.GetNumericValue(ch1);
Console.WriteLine("Метод GetNumericValue:");
Console.WriteLine("sym 'a' - value {0}", d1);
Console.WriteLine("sym '1' - value {0}", d2);
System.Globalization.UnicodeCategory cat1, cat2;
cat1 =char.GetUnicodeCategory(ch1);
cat2 =char.GetUnicodeCategory(lim);
Console.WriteLine("Метод GetUnicodeCategory:");
Console.WriteLine("sym '1' - category {0}", cat1);
Console.WriteLine("sym ';' - category {0}", cat2);
Console.WriteLine("Метод IsControl:");
Console.WriteLine("sym '\xA' - IsControl - {0}", char.IsControl(chc));
Console.WriteLine("sym ';' - IsControl - {0}", char.IsControl(lim));
Таблица 7
Метод |
Описание |
GetNumericValue |
Возвращает численное значение символа, если он является цифрой, и (-1) в противном случае |
GetUnicodeCategory |
Все символы разделены на категории. Метод возвращает Unicode категорию символа |
IsControl |
Возвращает true, если символ является управляющим |
IsDigit |
Возвращает true, если символ является десятичной цифрой |
IsLetter |
Возвращает true, если символ является буквой |
IsLetterOrDigit |
Возвращает true, если символ является буквой или цифрой |
IsLower |
Возвращает true, если символ задан в нижнем регистре |
IsNumber |
Возвращает true, если символ является числом (десятичной или шестнадцатиричной цифрой) |
IsPunctuation |
Возвращает true, если символ является знаком препинания |
IsSeparator |
Возвращает true, если символ является разделителем |
IsSurrogate |
Некоторые символы Unicode с кодом в интервале [0x1000, 0x10FFF] представляются двумя 16-битными "суррогатными" символами. Метод возвращает true, если символ является суррогатным |
IsUpper |
Возвращает true, если символ задан в верхнем регистре |
IsWhiteSpace |
Возвращает true, если символ является "белым пробелом". К белым пробелам, помимо пробела, относятся и другие символы, например, символ конца строки и символ перевода каретки |
Parse |
Преобразует строку в символ. Естественно, строка должна состоять из одного символа, иначе возникнет ошибка |
ToLower |
Приводит символ к нижнему регистру |
ToUpper |
Приводит символ к верхнему регистру |
MaxValue, MinValue |
Свойства, возвращающие символы с максимальным и минимальным кодом. Возвращаемые символы не имеют видимого образа |