"Сокрытие деталей реализации называется инкапсуляцией (от слова "капсула"). " Сколько можно объяснять?! ИНКАПСУЛЯЦИЯ НЕ РАВНА СОКРЫТИЮ!!! Инкапсуляция это парадигма ООП, которая ОБЕСПЕЧИВАЕТ СОКРЫТИЕ!!! НО СОКРЫТИЕМ НЕ ЯВЛЯЕТСЯ!!! Если буровая коронка обеспечивает разрушение породы, то является ли она сама разрушением породы? Конечно нет! |
Массивы, символы и строки
Массивы
Презентацию к данной лекции Вы можете скачать здесь.
Массив — это ограниченная совокупность однотипных величин. Элементы массива имеют одно и то же имя, а различаются по порядковому номеру ( индексу ).
Массив в С# относится к ссылочным типам данных, то есть располагается в динамической области памяти, поэтому создание массива начинается с выделения памяти под его элементы. Элементами массива могут быть величины как значимых, так и ссылочных типов (в том числе массивы). Массив значимых типов хранит значения, массив ссылочных типов — ссылки на элементы. Всем элементам при создании массива присваиваются значения по умолчанию: нули для значимых типов и null для ссылочных.
На рис. 6.1 представлен массив, состоящий из пяти элементов любого значимого типа, например, int или double, а рисунок 6.2 иллюстрирует организацию массива из элементов ссылочного типа.
Вот, например, как выглядят операторы создания массива из 10 целых чисел и массива из 100 строк:
int[] w = new int[10]; string[] z = new string[100];
В первом операторе описан массив w типа int[]. Операция new выделяет память под 10 целых элементов, и они заполняются нулями.
Во втором операторе описан массив z типа string[].Операция new выделяет память под 100 ссылок на строки, и эти ссылки заполняются значением null. Память под сами строки, составляющие массив, не выделяется — это будет необходимо сделать перед заполнением массива.
Количество элементов в массиве ( размерность ) не является частью его типа, оно задается при выделении памяти и не может быть изменено впоследствии. Размерность может задаваться не только константой, но и выражением. Результат вычисления этого выражения должен быть неотрицательным, а его тип должен иметь неявное преобразование к int, uint, long или ulong.
Элементы массива нумеруются с нуля, поэтому максимальный номер элемента всегда на единицу меньше размерности. Для обращения к элементу массива после имени массива указывается номер элемента в квадратных скобках, например:
w[4] z[i]
С элементом массива можно делать все, что допустимо для переменных того же типа. Если при работе с массивом значение индекса выходит за границы массива, генерируется исключение IndexOutOfRangeException.
Массивы одного типа можно присваивать друг другу. При этом происходит присваивание ссылок, а не элементов, как и для любого другого объекта ссылочного типа, например:
int[] a = new int[10]; int[] b = a; // b и a указывают на один и тот же массив
Все массивы в C# имеют общий базовый класс Array, определенный в пространстве имен System. В нем есть несколько полезных методов, упрощающих работу с массивами, например, методы получения размерности, сортировки и поиска. Мы рассмотрим эти методы немного позже в разделе "Класс System.Array".
В C# существуют три разновидности массивов: одномерные, прямоугольные и ступенчатые (невыровненные). О последних, менее распространенных, можно прочитать в учебнике (Павловская Т. А. С#. Программирование на языке высокого уровня. — СПб.: Питер, 2010), а сейчас займемся одномерными массивами.
Одномерные массивы
Одномерные массивы используются в программах чаще всего. Варианты описания массива:
тип[] имя; тип[] имя = new тип [ размерность ]; тип[] имя = { список_инициализаторов }; тип[] имя = new тип [] { список_инициализаторов }; тип[] имя = new тип [ размерность ] { список_инициализаторов };
Примеры описаний (один пример на каждый вариант описания):
int[] a; // 1 элементов нет int[] b = new int[4]; // 2 элементы равны 0 int[] c = { 61, 2, 5, -9 }; // 3 new подразумевается int[] d = new int[] { 61, 2, 5, -9 }; // 4 размерность вычисляется int[] e = new int[4] { 61, 2, 5, -9 }; // 5 избыточное описание
Здесь описано пять массивов. Отличие первого оператора от остальных состоит в том, что в нем фактически описана только ссылка на массив, а память под элементы массива не выделена.
В каждом из остальных массивов по четыре элемента целого типа. Как видно из операторов 3–5, массив при описании можно инициализировать. Если при этом не задана размерность (оператор 3), количество элементов вычисляется по количеству инициализирующих значений. Для полей объектов и локальных переменных можно опускать операцию new, она будет выполнена по умолчанию (оператор 2). Если присутствует и размерность, и список инициализаторов, размерность должна быть константой (оператор 4).
В качестве примера рассмотрим программу, которая определяет сумму и количество отрицательных элементов, а также максимальный элемент массива, состоящего из 6 целочисленных элементов (листинг 6.1).
using System; namespace ConsoleApplication1 { class Class1 { static void Main() { const int n = 6; int[] a = new int[n] { 3, 12, 5, -9, 8, -4 }; Console.WriteLine( "Исходный массив:" ); for ( int i = 0; i < n; ++i ) Console.Write( "\t" + a[i] ); Console.WriteLine(); long sum = 0; // cумма отрицательных элементов int num = 0; // количество отрицательных элементов for ( int i = 0; i < n; ++i ) if ( a[i] < 0 ) { sum += a[i]; ++num; } Console.WriteLine( "Сумма отрицательных = " + sum ); Console.WriteLine( "Кол-во отрицательных = " + num ); int max = a[0]; // максимальный элемент for ( int i = 1; i < n; ++i ) if ( a[i] > max ) max = a[i]; Console.WriteLine( "Максимальный элемент = " + max ); } } }Листинг 6.1. Работа с одномерным массивом
Обратите внимание, что для вывода массива требуется организовать цикл.