Шаг 203.
Язык программирования C#. Начала.
Перечисления и структуры. Примеры использования
На этом шаге мы рассмотрим несколько примеров решения задач, в которых используются структуры.
Здесь мы рассмотрим несколько программ, в которых используются ранее рассмотренные структуры.
Задание 1.
Напишите программу, содержащую структуру с целочисленным массивом. Опишите конструктор с одним аргументом, определяющим размер массива.
Массив должен заполняться случайными числами. В структуре должны быть методы, возвращающие результатом наибольший элемент в массиве,
наименьший элемент в массиве, а также метод, возвращающий среднее значение элементов в массиве (сумма элементов массива,
деленная на количество элементов в массиве).
Раскрыть/скрыть решение и комментарии.
Текст программы, надеемся, сложностей не вызывает. Само условие задачи определяет содержание структуры:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace pr203_1
{
// Структура:
struct MyStruct
{
// Ссылка на целочисленный массив:
public int[] mas;
// Конструктор
public MyStruct(int n)
{
// Объект для генерирования случайных чисел:
Random rnd = new Random();
mas = new int[n];
// Заполнение массива
for (int i = 0; i < n; i++)
{
// Значение элемента массива:
mas[i] = rnd.Next(20);
}
}
// Возврат максимального элемента в массиве:
public int maxEl()
{
int mx = mas[0];
for (int i = 0; i < mas.Length; i++)
if (mx < mas[i])
mx = mas[i];
return mx;
}
// Возврат минимального элемента в массиве:
public int minEl()
{
int mn = mas[0];
for (int i = 0; i < mas.Length; i++)
if (mn > mas[i])
mn = mas[i];
return mn;
}
// Возврат среднего значения массива:
public int avgEl()
{
int sum = 0;
for (int i = 0; i < mas.Length; i++)
sum += mas[i];
return sum / mas.Length;
}
// Метод для отображения содержимого массива:
public void show()
{
for (int k = 0; k < mas.Length; k++)
{
Console.Write("|" + mas[k]);
}
Console.WriteLine("|");
}
}
class Program
{
static void Main()
{
// Создание структуры:
MyStruct A = new MyStruct(6);
Console.WriteLine("Исходный массив:");
// Вывод структуры:
A.show();
// Вывод результатов:
Console.WriteLine("Максимальное значение в массиве: " + A.maxEl());
Console.WriteLine("Минимальное значение в массиве: " + A.minEl());
Console.WriteLine("Среднее значение в массиве: " + A.avgEl());
// Задержка:
Console.ReadLine();
}
}
}
Архив проекта можно взять
здесь.
Результат работы приложения приведен на рисунке 1.
Рис.1. Результат работы приложения
Надеемя, что приведенных комментариев достаточно, чтобы понять принцип работы приложения.
Задание 2.
Напишите программу, в которой объявлены две структуры. У одной структуры есть текстовое поле, а у другой структуры есть
символьное поле. В первой структуре (с текстовым полем) должен быть метод с целочисленным аргументом, который результатом
возвращает экземпляр второй структуры (с символьным полем). Значение символьного поля экземпляра-результата определяется
как символ из текста (поле экземпляра, из которого вызывается метод) с индексом, определяемым аргументом метода.
Раскрыть/скрыть решение и комментарии.
Текст программы, решающий эту задачу, может быть следующим:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace pr203_2
{
struct MyStructB
{
// Символьное поле:
public char ch;
// Конструктор:
public MyStructB(char ci)
{
ch = ci;
}
// Метод вывода поля:
public char show()
{
return ch;
}
}
struct MyStructA
{
// Текстовое поле:
public string text;
// Конструктор:
public MyStructA(string ti)
{
text = ti;
}
// Метод вывода поля:
public string show()
{
return text;
}
// Метод, возвращающий структуру
// с элементом, номер которого передается
// в качестве аргумента метода:
public MyStructB method1(int n)
{
// Создание и возврат структуры:
return new MyStructB((char)text[n]);
}
}
class Program
{
static void Main()
{
// Создаем первую структуру:
MyStructA A = new MyStructA("ABCDEFGH");
// Выводим ее значение:
Console.WriteLine("Структура A: " + A.show());
// Создаем вторую структуру как
// результат работы метода первой структуры:
MyStructB B = A.method1(3);
// Выводим ее значение:
Console.WriteLine("Структура B: " + B.show());
// Задержка:
Console.ReadLine();
}
}
}
Архив проекта можно взять
здесь.
Результат работы приложения изображен на рисунке 2.
Рис.2. Результат работы приложения
Обратите внимание, что вторая структура расположена раньше первой. Дело в том, что на момент описания первой структуры, вторая должна быть "известна" транслятору из-за того, что
результатом работы метода method1() должен быть экземпляр второй структуры. В команде
return new MyStructB((char)text[n]);
как раз создается экземпляр такой структуры, который инициализируется символом с номером n, взятым из строкового поля
text первой струкруры.
Задание 3.
Напишите программу, в которой объявлены две структуры. У первой структуры есть целочисленное поле, а у второй структуры есть
два целочисленных поля. Предложите операторный метод, с помощью которого сумма двух экземпляров первой структуры возвращала бы результатом экземпляр второй структуры
(поля экземпляра-результата - это поля суммируемых экземпляров). Во второй структуре опишите метод, который результатом возвращает массив
из двух экземпляров первой структуры. В этом случае экземпляр с двумя полями, из которого вызывается метод, "разбивается" на два
экземпляра, у каждого из которых по одному полю.
Раскрыть/скрыть решение и комментарии.
При решении этой задачи, "фокус", примененный при решении второй задачи, не пройдет. Дело в том, что при описании каждой из структур, должна быть "известна" другая структура, поэтому простой
переменой мест здесь не обойдемся. Одним из способов решения этой проблемы, может быть определение одного из методов статическим (это сделано для операторного метода в структуре MyStructA).
В этом случае мы должны явно прописать в его сигнатуре два параметра (self и other типа MyStructA), после чего использовать их для доступа к полям.
Вот текст программы:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace pr203_3
{
struct MyStructA
{
// Целочисленное поле:
public int ch;
// Конструктор:
public MyStructA(int n)
{
ch = n;
}
// Операторный метод:
static public MyStructB operator+(MyStructA self, MyStructA other)
{
return new MyStructB(self.ch, other.ch);
}
// Вывод значения:
public int show()
{
return ch;
}
}
struct MyStructB
{
// Два целочисленных поля:
public int ch1;
public int ch2;
// Конструктор:
public MyStructB(int n1, int n2)
{
ch1 = n1;
ch2 = n2;
}
// Вывод значения:
public string show()
{
return ch1 + " " + ch2;
}
// Метод, возвращающий массив структур:
public MyStructA[] methodB()
{
return new MyStructA[2]{new MyStructA(this.ch1), new MyStructA(this.ch2)};
}
}
class Program
{
static void Main()
{
// Создание одного экземпляра первой структуры:
MyStructA A1 = new MyStructA(3);
// Его вывод:
Console.WriteLine("Структура A1: " + A1.show());
// Создание другого экземпляра первой структуры:
MyStructA A2 = new MyStructA(5);
// Его вывод:
Console.WriteLine("Структура A2: " + A2.show());
// Суммирование двух первых структур:
MyStructB B = A1 + A2;
// Вывод полученной второй структуры:
Console.WriteLine("Структура B: " + B.show());
// Создание еще одной второй структуры:
MyStructB B1 = new MyStructB(10, 20);
// Его вывод:
Console.WriteLine("Структура B1: " + B1.show());
// Получение массива структур:
MyStructA[] A3 = B1.methodB();
// Вывод элементов массива:
Console.WriteLine("Структура A3[0]: " + A3[0].show());
Console.WriteLine("Структура A3[1]: " + A3[1].show());
// Задержка:
Console.ReadLine();
}
}
}
Архив проекта можно взять
здесь.
Результат работы приложения изображен на рисунке 3.
Рис.3. Результат работы приложения
Единственным местом, требующим комментария, на наш взгляд, является строка
return new MyStructA[2]{new MyStructA(this.ch1), new MyStructA(this.ch2)};
где происходит создание и возврат массива, состоящего из двух структур. Здесь конструкция
создает массив из двух элементов, каждый из которых имеет тип
MyStructA. Конструкцией
{new MyStructA(this.ch1), new MyStructA(this.ch2)}
осуществляется его инициализация. Здесь два элемента. Каждый элемент, например:
new MyStructA(this.ch1) ,
создает структуру типа
MyStructA и инициализирует ее значеним поля (в этом случае
ch1) структуры типа
MyStructB, для которой вызван метод
methodB() (об этом свидетельствует указатель
this).
Со следующего шага мы начнем знакомиться с указателями.
Предыдущий шаг
Содержание
Следующий шаг