Скачиваний:
3
Добавлен:
04.09.2023
Размер:
1.48 Mб
Скачать

Модификатор доступа (области видимости) может быть public, private, protected, internal.

Между модификатором и типом может стоять ключевое слово static, что означает, что функция будет статичной. Из статичной функции можно вызывать другие функции, если они тоже статичные. Главная функция main –

всегда static.

Функция может возвращать значение или не возвращать. Если функция,

например, возвращает целое число, то нужно указать тип int. Если функция не возвращает никакого значения, то для этого используется ключевое слово void. Функции, которые не возвращают значение, называют процедурами.

По умолчанию при передаче в метод экземпляра типа значения вместо самого этого экземпляра передается его копия. Поэтому изменения в аргументе не оказывают влияния на исходный экземпляр в вызывающем методе. Чтобы передать экземпляр типа значения по ссылке, используется ключевое слово ref.

При передаче в метод объекта ссылочного типа передается ссылка на этот объект. То есть метод получает не сам объект, а аргумент, который указывает расположение объекта. При изменении члена объекта с помощью этой ссылки это изменение отражается в аргументе в вызывающем методе,

даже если объект передается по значению.

Ключевое слове return также останавливает выполнение метода. Если тип возврата — void, инструкцию return без значения по-прежнему можно использовать для завершения выполнения метода. Без ключевого слова return

этот метод будет останавливать выполнение при достижении конца блока кода. Методы с типом возврата, отличным от void, должны использовать ключевое слово return для возврата значения.

Аргументы – это те данные, которые необходимы для выполнения функции. Аргументы записываются в формате [тип] [идентификатор]. Если аргументов несколько, они отделяются запятой. Аргументы могут отсутствовать.

Параметры и аргументы функции Определение метода задает имена и типы всех необходимых

параметров. Когда вызывающий код вызывает метод, он предоставляет конкретные значения, называемые аргументами, для каждого параметра.

Аргументы должны быть совместимы с типом параметра, но имя аргумента

(если есть), используемое в вызывающем коде, не обязательно должно совпадать с именем параметра, указанным в методе.

Первая строка функции, где указываются тип, имя, аргументы и т.д.

называется заголовком функции.

17 Массивы. Создание и инициализация. Ссылки на массив. Двухмерные

и многомерные массивы. Инициализация массивов. Невыровненные

массивы.

Массив – это конечная группа элементов одного типа, имеющая общее

имя.

1. Массивы относятся к ссылочным типам данных. Это значит, что в стеке хранится ссылка на выделенное пространство для элементов массива в куче/хипе/динамической памяти. Важно понимать, что массив хранится как последовательный набор элементов (значения идут тупо друг за другом), в то время как очень похожий на него список может быть хаотично разбросан по всей динамической памяти вперемешку с остальными ссылочными данными.

В каждом элементе списка есть адрес, где найти следующий элемент.

Получается, что адреса элементов массивов известны, можно сказать хочу 4ый элемент такого-то массива и получить его БЫСТРО, а в списках мы говорим,

чтобы получить 4ый элемент найди первый, в нем адрес второго, во втором

адрес третьего и там ты найдешь свой четвертый элемент, что ДОЛГО.

Динамиче

Массив

 

1

 

 

 

 

2

 

 

Динамическая память

3

4

5

Лист

3 (замыкающий элемент)

какой-то инородный элемент

1+ адрес следующего значения (2ки)

2+ адрес следующего значения (3ки)

какой-то инородный элемент

2.Массивы построены на основе класса System.Array, поэтому любой массив получает методы и свойства класса Array, что значительно упрощает работу с массивами.

3.Работа с массивами более безопасна, поскольку контролируется выход за границы массива.

4.По умолчанию элементам массива присваиваются начальные

значения.

Начальные значения:

для арифметических типов - 0,

для ссылочных типов - null,

для символов - пробел.

для логических – false

Имеются одномерные, многомерные и ступенчатые массивы.

Одномерный массив

тип[] имя_массива = new тип [размер];

Например: int[] a=new int [10]; это значит, что длина массива равна 10,

а внутри массива будет десять нулей, т.к. для арифметических типов значение по умолчанию 0.

Возможно объявление массива с инициализацией значений:

тип [] имя _массива=new тип [размер] {список инициализированных значений};

Например: int[] a= new int[4] {0, 1, 2, 3};

Но, если мы инициализируем какие-то значения сами, то код можно сократить: убрать размер, тип и даже ключевое слово new.

Пример: int[] a = { 1, 2, 3, 5 };

Многомерный массив

Массивы характеризуются таким понятием как ранг или количество

измерений. Выше мы рассматривали массивы, которые имеют одно измерение

(то есть их ранг равен 1) - такие массивы можно представлять в виде горзонтального ряда элемента. Но массивы также бывают многомерными. У

таких массивов количество измерений (то есть ранг) больше 1.

Массивы, которые имеют два измерения (ранг равен 2) называют

двухмерными.

Например, создадим одномерный и двухмерный массивы, которые

имеют одинаковые элементы:

int[] nums1 = new int[6] { 0, 1, 2, 3, 4, 5 };

0

1

2

3

4

5

 

 

 

 

 

 

int[,] nums2 = new int[2,3] { { 0, 1, 2 }, { 3, 4, 5 } };

0

1

2

3

4

5

Объявить двумерный массив можно одним из предложенных способов:

тип [,] a = new тип [размер 1, размер 2] {{эл - ты 1-ой строки}, … , {эл-

ты n-ой строки}};

тип [,] a ={{эл - ты 1-ой строки}, … , {эл-ты n-ой строки}};

Аналогично одномерному, мы можем не писать размеры ( int[,]), тип (

[,]) и даже ключевое слово new.

Ступенчатые массивы / Невыровненные массивы / Зубчатые

массивы

Иначе говоря, массив массивов. Ступенчатый массив объявляется с помощью идущих друг за другом пар квадратных скобок. Всегда задается столько пар квадратных скобок, сколько размерностей у массива.

Определение ступенчатых массивов:

int[][] arr = new int [3][]; // Объявляем ступенчатый массив

Размерность = 2, соответственно две пары кв. скобок - [][]. Внешнее измерение равно 3, значит в него войдет три каких-то массива (одномерных или многомерных). Последняя пара скобок [] – значит состоит из одномерных,

если бы была [ , ] – был бы набор двумерных, ну и так далее [ , , ] – уже набор трехмерных.

Дальше задаем элементы ступенчатого массива: arr[0] = new int[3]; // Определяем нулевой элемент arr[1] = new int[2]; // Определяем первый элемент arr[2] = new int[5]; // Определяем второй элемент

Каждый элемент представляет собой одномерный массив целых чисел.

Первый элемент массива состоит из трех целях чисел, второй – из двух и третий – из пяти.

Внутреннее измерение при объявлении не указывается, поскольку в отличие от прямоугольного массива, в невыровненном каждый внутренний массив может иметь разную длину. Каждому внутреннему массиву автоматически присваивается значение null, а не пустой массив, и поэтому каждый внутренний массив нужно объявлять отдельно.

18 Понятие класса. Определение класса и экземпляр класса. Данные

и методы. Ключевое слово partial.

Класс является типом данных, определяемым пользователем. Он должен представлять собой одну логическую сущность, например, являться моделью реального объекта или процесса. Элементами класса являются данные и функции/методы, предназначенные для их обработки. Проще сравнить класс с шаблоном объекта, в нем есть все, чтобы описать любую машину, любого человека, любое дерево и т.д. Каждый новый экземпляр класса будет иметь общие для класса черты, но по-разному с ними работать: изменять значения

(данные), добавлять новые, удалять с помощью блоков кода, называемых методами/функциями.

Данные, содержащиеся в классе, могут быть переменными или константами. Переменные и константы, описанные в классе, называются полями класса. При описании полей (на самом деле не только полей, но методов и даже самого класса) можно указывать атрибуты и спецификаторы/модификаторы, задающие различные характеристики элементов. Пример переменной: public int age; Пример константы: public const double Pi = 3.14159; public – это модификатор, делающий поле доступным вне класса.

Метод – функциональный элемент класса, реализующий вычисления или другие действия. Методы определяют поведение класса и составляют его интерфейс. К методу можно обратиться по имени. Он описывается один раз, а

вызываться может столько раз, сколько необходимо. Один и тот же метод может обрабатывать различные данные, переданные ему в качестве аргументов.

Создание любого метода следует начинать с его интерфейса (заголовка).

Необходимо четко представлять себе, какие параметры метод должен получать и какие результаты формировать. Входные параметры обычно перечисляют в начале списка параметров.

Тип возвращаемого значения _ название метода(входные аргументы)

int Square(int i)

{

int input = i;

return input * input;

}

Если функция ничего не возвращает, то вначале пишется void Square(int i) вместо int. Кроме того, вначале может стоять какой-либо модификатор, например, тот же public или protected, или public virtual / public abstract int Square(int i).

Можно разделить определение класса, структуры, интерфейса или метода между двумя или более исходными файлами. Каждый исходный файл содержит часть определения класса или метода, а во время компиляции приложения все части объединяются.

Для разделения определения класса используется ключевое слово partial.

Ключевое слово partial указывает, что другие части класса могут быть определены в общем пространстве имен. Т.е. грубо говоря под общим пространством имен, подразумевается, что другие части класса описаны внутри одного проекта, может в разных файлах, может в разных частях одного файла. Все части должны использовать ключевое слово partial. Для формирования окончательного типа все части должны быть доступны во время компиляции. Все части должны иметь одинаковые модификаторы доступа, например public, private и т. д.

Любые члены класса, объявленные в разделяемом объявлении,

доступны для всех остальных частей. Модификатор partial нельзя использовать для перечисления. Если какая-то часть (partial) класса является abstract, то весь класс будет abstract и так по аналогии с другим модификаторами, вроде, sealed. Кроме того, если какая-то часть наследует базовый класс, остальные тоже это делают.

Дополнительно

Помимо модификаторов доступа есть еще целая куча прочих модификаторов: abstract, async, const, event, extern, in, new, out, override, readonly, sealed, static, unsafe, virtual, volatile.

Например, статичная переменная static принадлежит классу, а не экземпляру, это значит, если в одном из экземпляров произойдет переопределение static переменной – она изменится сразу во всех экземплярах.

К тому же ссылаться на static можно только через имя класса. Или вот, Abstract - класс, предназначенный только для использования в качестве базового класса для других классов и не существующий сам по себе.

Атрибуты представляют специальные инструменты, которые позволяют встраивать в сборку дополнительные метаданные. Атрибуты могут применяться как ко всему типу (классу, интерфейсу и т.д.), так и к отдельным его частям (методу, свойству и т.д.). Пример применения атрибута: проверяем соответствие возраста (переменной Age) заданному значению (18 лет) в нашем классе Person. Создаем атрибут, пишем его наименование непосредственно над классом в квадратных скобках и указываем пороговую величину возраста: [AgeValidation(18)], создаем функцию, которая получит класса все заданные для класса атрибуты, выберет первый атрибут, сверит данные и вернет true или false, затем прейдет к следующему атрибуту, если он есть.

19 Создание объекта класса.

Создание объекта класса с помощью оператора «new».

Инициализация данных класса. Конструкторы.

Класс представляет новый тип, который определяется пользователем.

После слова class идет имя класса и далее в фигурных скобках идет собственно содержимое класса.

Класс может хранить некоторые данные. Для хранения данных в классе применяются поля (переменные, определенные на уровне класса).

Кроме того, класс может определять некоторое поведение или

выполняемые действия. Для определения поведения в классе применяются

методы.

class Класс

{

private ТипПеременной Поле1; // private – внутренняя переменная public ТипПеременной Поле2; // public – общая переменная

public ТипПеременной Поле3 = ЗначениеПоУмолчанию;

public void Метод() // Метод void не возвращает переменные

{

Оператор1(Поле2); Оператор2();

}

public Класс (ТипПеременной Параметр1, ТипПеременной Парметр2) // Конструктор класса

{

Поле1 = Параметр1; Оператор2();

}

}

После определения класса мы можем создавать его объекты. Для создания объекта применяются конструкторы. По сути конструкторы представляют специальные методы, которые называются так же как и класс, и

которые вызываются при создании нового объекта класса и выполняют инициализацию объекта. Общий синтаксис вызова конструктора:

Класс Объект = new Класс(ПараметрыКонструктора);

Если в классе не определено ни одного, то для этого класса автоматически создается пустой конструктор по умолчанию, который не принимает никаких параметров.

Для обращения к функциональности класса - полям, методам (а также другим элементам класса) применяется точечная нотация точки - после объекта класса ставится точка, а затем элемент класса:

Объект.ПолеКласса

Объект.МетодКласса(ПараметрыМетода)

20 Деструкторы и «сборка мусора». Оператор «new». Резервирование и

освобождение памяти. Деструкторы и «сборка мусора».

В программах на C# память для объектов нужно выделять динамически.

Динамическое выделение памяти для объектов или других видов данных реализуется с помощью оператора new (просим программу выделить нам память, например, для переменной). Общая форма оператора new:

new ClassName(parameters_list)

где ClassName – имя класса, для объекта которого выделяется память; parameter_list – список параметров, которые принимает один из

конструкторов класса. Обязательно, в классе должен быть реализован конструктор, параметры которого совпадают с parameter_list. Конструктор может быть без параметров (конструктор по умолчанию).

После того, как объект выполнил свою работу, он (возможно) уже не используется в программе (но память все еще занимает). Если в программе создано много объектов классов, то может возникнуть ситуация, когда выделенной памяти не хватит для создания следующего объекта.

В этом случае, важно освободить память что была выделена под объекты, которые уже не используются. Для этого система динамического распределения памяти C# использует так называемую «сборку мусора». Если происходит «сборка мусора», то освобождается память для объектов, которые не используются.

Чтобы определить, используется объект или нет, система «сборки мусора» просматривает ссылки на этот объект на данный момент. Если ссылки отсутствуют, то этот объект считается ненужным и можно выполнять освобождение памяти для него. В дальнейшем эта освобожденная память может быть использована для распределения других объектов.

Если использованный объект становится ненужным, то выделенная для него память может быть освобождена не сразу, а позднее. В системе динамического управления памятью C# «сборка мусора» происходит только время от времени во время выполнения программы. «Сборка мусора» может не происходить если есть небольшое количество неиспользуемых объектов.