Модуль 1. Алгоритми і абстрактні структури даних Лекція 4. Cтруктури
4.1. Структури у мові C#
4.2. Масиви структур у C#
4.1. Структури у мові c#
Структури у C# відносяться до статичного типу даних (типу-значення). Це означає, що пам’ять для них компілятор відводить у стеку. Синтаксис оголошення структури подібний до синтаксису оголошення класу. У багатьох випадках структури працюють швидше за об’єкти класів.
Головна різниця між структурами і класами полягає в тому, що при оголошенні структури використовується ключове слово struct замість class. Крім того, для структур заборонено спадкування. Нижче наведена загальна форма оголошення структури :
struct ім’я : [інтерфейси]
{
// оголошення членів структури
}
Як і у класі, у структури є свої члени: методи, поля, індексатори, властивості і події. У структурах допускається також визначати конструктори, але не деструктори. В той же час для структури не можна визначити конструктор за замовчанням (тобто конструктор без параметрів). Річ у тому, що конструктор, що викликається за замовчанням, визначається для усіх структур автоматично і не підлягає зміні. Такий конструктор ініціалізує поля структури значеннями, що задаються за замовчанням. А оскільки структури не підтримують спадкування, то їх члени не можна вказувати як abstract, virtual або protected.
Об'єкт структури може бути створений за допомогою оператора new так само, як і об'єкт класу, але в цьому немає особливої необхідності. Адже, коли використовується оператор new, то викликається конструктор за замовчанням. А коли цей оператор не використовується, об'єкт як і раніше створюється, хоча і не ініціалізується. В цьому випадку ініціалізацію будь-яких членів структури доведеться виконати вручну.
Приклад використання структур.
У наступному прикладі оголошується структура UserInfo з полями Name і Age. Конструктор структури ініціалізує поля, а метод WriteUserInfo() виводить на консоль їх значення.
В методі main створюються об’єкти структури user1 і user2.
Приклад 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab4_2
{
// Оголошення структури
struct UserInfo
{
public string Name;
public byte Age;
public UserInfo(string Name, byte Age)
{
this.Name = Name;
this.Age = Age;
}
public void WriteUserInfo()
{
Console.WriteLine("Ім'я: {0}, вік: {1}",Name,Age);
}
}
class Program
{
static void Main()
{
UserInfo user1 = new UserInfo("Alexandr", 20);
Console.Write("user1: ");
user1.WriteUserInfo();
UserInfo user2 = new UserInfo("Elena",22);
Console.Write("user2: ");
user2.WriteUserInfo();
// Показати головну відмінність структур від класів
user1 = user2;
user2.Name = "Natalya";
user2.Age = 25;
Console.Write("\nuser1: ");
user1.WriteUserInfo();
Console.Write("user2: ");
user2.WriteUserInfo();
Console.ReadKey();
}
}
}
Зверніть увагу, що коли одна структура призначається іншій, створюється копія її об'єкту. У цьому полягає одна з головних відмінностей структури від класу. Коли посилання на один клас призначається посиланню на інший клас, у результаті посилання в лівій частині оператора призначення вказує на той самий об'єкт, що і посилання у правій його частині. А коли змінна однієї структури призначається змінній іншої структури, створюється копія об'єкту структури з правої частини оператора призначення.
Приклад 3. Структура Person
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab4_Structure
{
struct Person
{
string Name;
string Role;
int Age;
string Address;
public Person(string name, string role, int age, string address)
{
//конструктор з параметрами. Ініціалізація полів
this.Name = name;
this.Role = role;
this.Age = age;
this.Address = address;
}
public void Print_Person ()
{
Console.WriteLine("Ім'я= {0}, Роль= {1}, Вік = {2}, Адреса = {3}", Name, Role, Age, Address);
}
}
class Program
{
static void Main(string[] args)
{
Person student = new Person("Іванов", "студент", 20,"Киев");
student.Print_Person();
Console.ReadKey();
}
}
}
Вкладені структури
Структури можна вкладати одну в одну. Тобто, членом структури може бути інша структура. В наступному прикладі у структурі Person використовується структура Address. Поля структури Address ініціалізуються у конструкторі структури Person.
Приклад 3.
using System.Text;
namespace Lab4_Structure
{
// Вкладені структури
struct Person
{
string Name;
string Role; // роль
int Age;
Address my_address; // змінна структури Address
public Person(string name, string role, int age, string town, string street, byte house)
{
//конструктор з параметрами. Ініціалізація полів і властивостей
this.Name = name;
this.Role = role;
this.Age = age;
my_address.town = town;
my_address.street = street;
my_address.house = house;
}
public void Print_Person ()
{
Console.WriteLine("Ім'я= {0}, Роль= {1}, Вік = {2}, Місто = {3},Вулиця= {4}, Дім= {5}", Name, Role, Age,my_address.town,my_address.street,my_address.house);
}
struct Address
{
public string town;
public string street;
public byte house;
}
}
class Program
{
static void Main(string[] args)
{
Person student = new Person("Іванов", "студент", 20,"Киев", "Магнитог",3);
student.Print_Person();
Console.ReadKey();
}
}
}
Використання масивів у структурах
Членами структури можуть бути масиви. У наступному прикладі у структурі Person додано масив оцінок з їх ініціалізацією. Оскільки структура є типом-значенням, то масив повинен оголошуватися як статичний. У цій структурі є 3 методи. Метод Rating обчислює середню оцінку, метод Print_mark виводить на консоль оцінки з масиву, метод Print_Person виводить інформацію про студента.
Приклад 4.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab4_Structure
{
struct Person
{
string Name;
string Role;
int Age;
string Address;
public static float [] mark = new float [] { 35, 34, 65 }; //масив оцінок
public Person(string name, string role, int age, string address)
{
//конструктор з параметрами. Ініціалізація полів
this.Name = name;
this.Role = role;
this.Age = age;
this.Address = address;
}
public double Rating ()
{
//метод обчислює рейтинг за оцінками і повертає результат
double myRating=0;
for (int i = 0; i < mark.Length; i++)
myRating += mark[i];
return myRating / mark.Length;
}
public void Print_Person()
{
//метод виводить інформацію про студента
Console.WriteLine("Ім'я= {0}, Роль= {1}, Вік = {2}, Адреса = {3}", Name, Role, Age, Address);
}
public void Print_mark()
{
//метод виводить оцінки
for (int i = 0; i < mark.Length; i++)
Console.WriteLine("оцінка = " + mark[i]);
}
}
class Program
{
static void Main(string[] args)
{
Person student = new Person("Іванов", "студент", 20,"Киев"); //створення екземпляру структури
student.Print_Person(); //виведення інформації про студента
student.Print_mark(); //виведення оцінок
double myRating = student.Rating(); //обчислення рейтингу
Console.WriteLine("Рейтинг: {0}", myRating);
//призначення значень елементам масиву оцінок
Person.mark[0] = 65; //масив є static, тому вказується ім'я структури, а не екземпляра
Person.mark[1] = 65;
Console.WriteLine("Нові оцінки і рейтинг");
student.Print_mark(); //виведення нових оцінок
myRating = student.Rating(); //обчислення рейтингу
Console.WriteLine("Новий рейтинг: {0}", myRating);
Console.ReadKey();
}
}
}
Приклад 5.
Є модифікацією прикладу 4. В ньому ініціалізація масиву виконується у конструкторі. При цьому вже не потрібно оголошувати поле mark статичним.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lab4_Structure
{
struct Person
{
string Name;
string Role;
int Age;
string Address;
public float [] mark;
public Person(string name, string role, int age, string address, float [] mark)
{
//конструктор з параметрами. Ініціалізація полів
this.Name = name;
this.Role = role;
this.Age = age;
this.Address = address;
this.mark = mark;
}
public double Rating ()
{
//метод обчислює рейтинг за оцінками і повертає результат
double myRating=0;
for (int i = 0; i < mark.Length; i++)
myRating += mark[i];
return myRating / mark.Length;
}
public void Print_Person()
{
//метод виводить інформацію про студента
Console.WriteLine("Ім'я= {0}, Роль= {1}, Вік = {2}, Адреса = {3}", Name, Role, Age, Address);
}
public void Print_mark()
{
//метод виводить оцінки
for (int i = 0; i < mark.Length; i++)
Console.WriteLine("оцінка = " + mark[i]);
}
}
class Program
{
static void Main(string[] args)
{
float[] mark = {23,33,43};
Person student = new Person("Іванов", "студент", 20,"Киев", mark); //створення екземпляру структури
student.Print_Person(); //виведення інформації про студента
student.Print_mark(); //виведення оцінок
for (int i = 0; i < student.mark.Length; i++)
{
student.mark[i] = 65 + i;
}
student.Print_mark(); //виведення оцінок
double myRating = student.Rating(); //обчислення рейтингу
Console.WriteLine("Рейтинг: {0}", myRating);
//призначення значень елементам масиву оцінок
student.mark[0] = 65; //масив є static, тому вказується ім'я структури, а не екземпляра
student.mark[1] = 65;
student.mark[2] = 75;
Console.WriteLine("Нові оцінки і рейтинг");
student.Print_mark(); //виведення нових оцінок
myRating = student.Rating(); //обчислення рейтингу
Console.WriteLine("Новий рейтинг: {0}", myRating);
Console.ReadKey();
}
}
}