ОТЧЕТ
По лабораторной работе
По дисциплине «Алгоритмизация и программирование»
Студент: А.С.Блинков
Группа НМт-263907
Преподаватель:
профессор, д.т.н. И.А.Гурин
Екатеринбург
Практическая работа №3 «Работа с примитивными, ссылочными и значимыми типами»
Работа со структурой
a. Создать Класс с одним полем, тип поля брать из варианта.
Вариант 3. Типshort
Тип shortимеет диапазон значений от -32 768 до 32 767, по размеру является 16-разрядным целым числом со знаком, в NET.Framework записывается как System.Int16 или short.
classSs
{
publicshort memory;
}
b. Создать Структуру с одним полем, тип поля брать из варианта.
Структура подобна классу, но относится к типу значения, а не к ссылочному типу данных.
Т.е. структуры отличаются от классов тем, как они сохраняются в памяти и как к ним осуществляется доступ (классы — это ссылочные типы, размещаемые в куче, структуры — типы значений, размещаемые в стеке)
Вариант 3. Типshort
structPp
{
publicshort memory;
}
c. Создать экземпляр класса ( classSs ) и структуры ( structPp ).
Pp one = newPp();
Ss two = newSs();
Присвоить полям произвольные значения.
one.memory = 64;
two.memory = 128;
Вывести значения в консоль.
Console.WriteLine("Значение 1 (структура): " + one.memory);
Console.WriteLine("Значение 2 (класс): " + two.memory + "\n");
d. Объявить переменную типа Класс, объявить переменную типа структура.
Для наглядности будем присваивать одинаковые значения.
Ppone2 = newPp();
one2.memory = 16;
one2.InfoMemory(); //16
Ss two2 = newSs();
two2.memory = 16;
two2.InfoClass(); //16
Присвоить им значения ранее созданных экземпляров.
Структура:
one2 = one;
one.InfoMemory(); //64
one2.InfoMemory(); //64
Класс:
two2 = two;
two.InfoClass(); //128
two2.InfoClass(); //128
e. Изменить значения в переменных экземпляра класса ( classSs ) и структуры ( structPp ).
Структура:
one.memory = 2;
Console.WriteLine("Значение 1 после присвоения числа 2: ");
one.InfoMemory(); //2
Console.WriteLine("Значение 3 после присвоения числа 2: ");
one2.InfoMemory(); //64
Класс:
two.memory = 2;
Console.WriteLine("Значение 2 после присвоения числа 2: ");
two.InfoClass(); //2
Console.WriteLine("Значение 4 после присвоения числа 2: ");
two2.InfoClass(); //2
Вывести значения в консоль, изменились ли значения в новых переменных?
Вывод: как говорилось выше - структура относится к типу значения, а класс к ссылочному типу данных, следовательно, структура будет принимать разные значения, в то время, как класс будет принимать одинаковые значения.
Передача объекта как параметра метода
a. Создать класс с 2 полями - один из вариант, второй - string.
Вариант 3. Типshort
classCar
{
publicstring model;
publicshort year;
}
Далее в практической работе, для наглядности, я решил рассмотреть 2 случая не только со ссылкой ref, но также посмотреть, что будет без нее.
Все действия были выполнены по указаниям к практической работе!
Рассмотрим первый случай без ссылки ref:
b. Создадим методFullInfoCar, который в качестве параметра принимает объект Car:
staticvoidFullInfoCar()
{
Console.WriteLine("Перменные класса имеют значения: Mercedes E63s AMG и 2018\nПеременные метода имеют значения: Audi RS7 и 2017\nПеременные экземпляра имеют значения: BMW X6M и 2016\n");
Carthebest = newCar{ model = "BMW X6M", year = 2016 }; //Несработает
InfoCar(thebest);
Console.WriteLine("Модельавтомобиля: " + thebest.model);
Console.WriteLine("Годвыпуска: " + thebest.year);
}
c. Создадим метод InfoCarдля вывода информации о FullInfoCar:
staticvoidInfoCar(Car _car)
{
_car.model = "Audi RS7";
_car.year = 2017;
_car = newCar{ model = "Mercedes E63s AMG", year = 2018 };
Console.WriteLine("Модельавтомобиля: " + _car.model + "\nГодвыпуска: " + _car.year + "\n");
}
Моя идея заключается в том, что:
1. Создается объект thebest, которому присваиваются значения
2. Для вывода информации об этом объекте создается отдельны метод
3. В этом методе создается новый объект _car, следовательно, создается и новый объект в памяти
4. Следовательно, _car будет уже указывать на новый объект, а не на объект из FullInfoCar
5. Тогда, строки:
Console.WriteLine("Модель автомобиля: " + thebest.model);
Console.WriteLine("Годвыпуска: " + thebest.year);
Будут выводить MercedesE63sAMG и 2018
А, строки:
Console.WriteLine("Модель автомобиля: " + _car.model + "\nГод выпуска: " + _car.year + "\n");
Будут выводить AudiRS7 и 2017
Рассмотрим второй случай с использованием ссылки ref
a. Сделаем тоже самое, но при этом используя ссылку ref
Для этого:
1. Создадим новы класс
2. Создадим 2 метода
classCarRef
{
publicstringmodelRef;
publicshortyearRef;
}
b. Создадим метод FullInfoCarRef, который в качестве параметра принимает объект CarRef:
staticvoidFullInfoCarRef()
{
Console.WriteLine("Перменные класса имеют значения: Mercedes E63s AMG и 2018\nПеременные метода имеют значения: Audi RS7 и 2017\nПеременные экземпляра имеют значения: BMW X6M и 2016\n");
CarRefthebestRef = newCarRef{ modelRef = "BMW X6M", yearRef = 2016 }; // Несработает
InfoCarRef(refthebestRef);
Console.WriteLine("Модельавтомобиля: " + thebestRef.modelRef);
Console.WriteLine("Годвыпуска: " + thebestRef.yearRef);
}
c. Создадим метод InfoCarRef для вывода информации о FullInfoCarRef:
staticvoidInfoCarRef(refCarRef _carRef)
{
_carRef.modelRef = "Audi RS7";
_carRef.yearRef = 2017;
_carRef = newCarRef{ modelRef = "Mercedes E63s AMG", yearRef = 2018};
Console.WriteLine("Модельавтомобиля: " + _carRef.modelRef + "\nГодвыпуска: " + _carRef.yearRef + "\n");
}
По той же схеме проверим со ссылкой ref, а именно:
1. Создается объект thebestref, которому присваиваются значения
2. Для вывода информации об этом объекте создается отдельны метод, передаем значения этому методу по ссылке
3. В этом методе создается новый объект _carRef, которому задаются значения
4. Следовательно, и thebestRefи _carRef.ModelRefи _carRef.yearRef примут значения _carRef, так как, при передаче параметра по ссылке в метод в качестве аргумента передается сама ссылка на объект в памяти.
Поэтому можно изменить как поля и свойства объекта, так и сам объект.
Операция new создаст новый объект в памяти, и теперь ссылка _carRef(она же ссылка thebestRef из метода FullInfoCarRef)будет указывать уже на новый объект в памяти, следовательно FullInfoCarRef и InfoCarRef будут выводить одинаковые значения.
5. Тогда, строки:
Console.WriteLine("Модель автомобиля: " + thebestRef.modelRef);
Console.WriteLine("Годвыпуска: " + thebestRef.yearRef);
Будут выводить MercedesE63sAMG и 2018
И строки:
Console.WriteLine("Модель автомобиля: " + _carRef.modelRef + "\nГод выпуска: " + _carRef.yearRef + "\n");
Тоже будут выводить MercedesE63sAMG и 2018
Вывод: при написании этой практической работы, я узнал, чем отличаются структуры и классы, а также узнал отличия случаев при наличии ссылки ref и без нее.
Полныйкод:
using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespace ConsoleApp10
{
structPp
{
publicshort memory;
publicvoidInfoMemory()
{
Console.WriteLine("Количествопамяти: " + memory);
}
}
classSs
{
publicshort memory;
publicvoidInfoClass()
{
Console.WriteLine("Количествопамяти: " + memory);
}
}
classCar
{
publicstring model;
publicshort year;
}
classCarRef
{
publicstringmodelRef;
publicshortyearRef;
}
classProgram
{
staticvoid Main(string[] args)
{
Pp one = newPp();
one.memory = 64;
Ss two = newSs();
two.memory = 128;
Console.WriteLine("Задача №1\n");
Console.WriteLine("Создать экземпляр класса (ЭкземплярК) и структуры (ЭкземплярС).\nПрисвоить полям произвольные значения.\nВывести значения в консоль:\n");
Console.WriteLine("Значение 1 (структура): ");
one.InfoMemory();
Console.WriteLine("Значение 2 (класс): ");
two.InfoClass();
Console.WriteLine("\nОбъявить переменную типа Class, объявить переменную типа Struct, присвоить им значения ранее созданных экземпляров:\nОбъявленные значения 1* и 2*\n");
//Соструктурой
Pp one2 = newPp();
one2.memory = 16;
Console.WriteLine(" Значение 3 (структура): ");
one2.InfoMemory(); //16
Console.WriteLine("Присваиваем значению 3 значение 1: ");
one2 = one;
Console.WriteLine("Значение 1 послеприсвоения: ");
one.InfoMemory(); //64
Console.WriteLine("Значение 3 после присвоения: ");
one2.InfoMemory(); //64
Console.WriteLine("Присвоимзначеню1 число 2 ");
one.memory = 2;
Console.WriteLine("Значение 1 после присвоения числа 2: ");
one.InfoMemory(); //2
Console.WriteLine("Значение 3 после присвоения числа 2: ");
one2.InfoMemory(); //64
//Склассом
Ss two2 = newSs();
two2.memory = 16;
Console.WriteLine("\n \n Значение 4 (класс): ");
two2.InfoClass(); //16
Console.WriteLine("Присваиваемзначению4 значение 2: ");
two2 = two;
Console.WriteLine("Значение 2 после присвоения: ");
two.InfoClass(); //128
Console.WriteLine("Значение 4 после присвоения: ");
two2.InfoClass(); //128
Console.WriteLine("Присвоимзначеню2 число 2 ");
two.memory = 2;
Console.WriteLine("Значение 2 после присвоения числа 2: ");
two.InfoClass(); //2
Console.WriteLine("Значение 4 после присвоения числа 2: ");
two2.InfoClass(); //2
//!!! ЗАДАЧА2!!!
Console.WriteLine("\nЗадача №2\n");
Console.WriteLine("Без использования ref\n");
FullInfoCar();
Console.WriteLine("\nИтог: BMW X6M и 2016 выведено не будет\n");
Console.WriteLine("С использованием ref\n");
FullInfoCarRef();
Console.WriteLine("\nИтог: BMW X6M и 2016 И Audi RS7 и 2017 выведено не будет\n");
Console.ReadKey();
}
staticvoidFullInfoCar()
{
Console.WriteLine("Перменные класса имеют значения: Mercedes E63s AMG и 2018\nПеременные метода имеют значения: Audi RS7 и 2017\nПеременные экземпляра имеют значения: BMW X6M и 2016\n");
Carthebest = newCar{ model = "BMW X6M", year = 2016 }; //Несработает
InfoCar(thebest);
Console.WriteLine("Модельавтомобиля: " + thebest.model);
Console.WriteLine("Годвыпуска: " + thebest.year);
}
staticvoidInfoCar(Car _car)
{
_car.model = "Audi RS7";
_car.year = 2017;
_car = newCar{ model = "Mercedes E63s AMG", year = 2018 };
Console.WriteLine("Модельавтомобиля: " + _car.model + "\nГодвыпуска: " + _car.year + "\n");
//Строка _car = new Car { model = "Mercedes E63s AMG", year = 2018 } создастновыйобъектвпамяти,
//и _car теперь будет указывать на новый объект в памяти.
//Даже если после этого изменить ее, то это никак не повлияет на ссылку thebest в методе FullInfoCar,
//поскольку ссылка thebest все еще указывает на старый объект в памяти.
}
staticvoidFullInfoCarRef()
{
Console.WriteLine("Перменные класса имеют значения: Mercedes E63s AMG и 2018\nПеременные метода имеют значения: Audi RS7 и 2017\nПеременные экземпляра имеют значения: BMW X6M и 2016\n");
CarRefthebestRef = newCarRef{ modelRef = "BMW X6M", yearRef = 2016 }; // Несработает
InfoCarRef(refthebestRef);
Console.WriteLine("Модельавтомобиля: " + thebestRef.modelRef);
Console.WriteLine("Годвыпуска: " + thebestRef.yearRef);
}
staticvoidInfoCarRef(refCarRef _carRef)
{
_carRef.modelRef = "Audi RS7";
_carRef.yearRef = 2017;
_carRef = newCarRef{ modelRef = "Mercedes E63s AMG", yearRef = 2018 };
Console.WriteLine("Модельавтомобиля: " + _carRef.modelRef + "\nГодвыпуска: " + _carRef.yearRef + "\n");
//При передаче параметра по ссылке в метод в качестве аргумента передается сама ссылка на объект в памяти.
//Поэтому можно изменить как поля и свойства объекта, так и сам объект.
//Операция new создаст новый объект в памяти, и теперь ссылка _car(она же ссылка thebest из метода Main)
//будет указывать уже на новый объект в памяти, следовательноFullInfoCarRef и InfoCarRef будут выводить одинаковые значения.
}
}
}