Двумерный массив такого вида объявляется следующим образом: <базовыйТип> [,] <имя>;
Описания массивов с большим числом размерностей требуют больше запятых. Например:
<базовыйТип>[,,,] <имя>;
Так объявляется четырехмерный массив.
Для присваивания значений используется аналогичный синтаксис, причем размерности отделяются одна от другой запятыми. Для того чтобы объявить и инициализировать обсуждавшийся выше двумерный массив hillHeight с базовым типом double, размерностью х, равной 3, и размерностью у, равной 4, необходима следующая строка.
double[,] hillHeight = new double[3,4];
В качестве альтернативы при начальном присваивании значений могут использоваться литеральные значения. Для этого воспользуемся вложенными блоками, взятыми в фигурные скобки и разделенными запятыми. Например:
double[,] hillHeight = new {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
Этот массив имеет точно такие же описания размерностей, что и предыдущий, однако в данном случае значения элементов массива задаются явно.
Для того чтобы получить доступ к отдельным элементам многомерного массива, следует указать индексы этого элемента, разделенные запятыми. Например:
hillHeight[2,l]
Теперь над этим элементом можно выполнять действия так же, как и над другими элементами.
Это выражение позволяет получить доступ ко второму элементу третьего вложенного массива в соответствии с вышеприведенным описанием (в данном случае значение равняется 4). Отсчет начинается с 0 и что первая цифра относится к вложенному массиву, т.е. первая цифра определяет номер пары фигурных скобок, а вторая цифра определяет соответствующий элемент внутри этой пары фигурных скобок.
Цикл foreach позволяет осуществлять доступ ко всем элементам многомерных массивов так же, как и в случае одномерных. Например:
double [,] hillHeight = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}}; | |
foreach (double height in hillHeight) | |
Console.WriteLine("{0}", height); ) |
{
Элементы этого массива будут выводиться в том же порядке, в котором происходило присваивание им литеральных значений: hillHeight[0,0], hillHeight[0,1], hillHeight[0,2], hillHeight[0,3], hillHeight[1,0], hillHeight[1,1], hillHeight[1,2] и т д.
3.2.7.Массивы массивов
Многомерные массивы, обсуждавшиеся в предшествующем разделе, обычно называются прямоугольными, поскольку у них каждая "строка" имеет один и тот же размер. Если использовать предыдущий пример, то координата у может изменяться от 0 до 2 для любой координаты х.
Однако существует возможность использовать ступенчатых (jagged) массивов, у которых "строки" могут быть неодинакового размера. Для этого требуется массив, каждым элементом которого также является массив. При желании можно использовать массивы массивов массивов и даже более сложные конструкции. Однако это оказывается возможным только в том случае, если все массивы имеют один и тот же базовый тип.
Синтаксис, применяемый для объявления массивов массивов, подразумевает использование в объявлении массива нескольких пар квадратных скобок, например
int[ ] [ ] jaggedIntArray;
К сожалению, инициализация подобных массивов оказывается не таким простым делом, как инициализация многомерных массивов Так, например, мы не имеем возможности использовать вслед за этим объявлением следующую запись jaggedIntArray = new int[3] [4];
Но даже в том случае, если бы мы могли применять запись такого вида, вряд ли от этого была бы какая-нибудь польза, поскольку в случае многомерных массивов точно такого же эффекта можно достичь с меньшими затратами.
Следующий код также является недопустимым
jaggedIntArray = {{1, 2, 3}, {1}, {1, 2}};
На самом деле существуют две возможности. Можно сначала инициализировать массив, содержащий другие массивы (чтобы избежать путаницы, мы будем называть вложенные массивы субмассивами), а затем, в свою очередь, инициализировать эти субмассивы: jaggedIntArray = new int[2] []; jaggedIntArray [0] = new int[3]; jaggedIntArray [1] = new int[4];
Можно также воспользоваться видоизмененной формой приведенного выше литерального присваивания jaggedIntArray = {new int[] {1, 2, 3}, new int[] {1}, new int[] {1, 2}};
Для таких неоднородных массивов можно использовать циклы foreach, однако чаще всего вложенные циклы применяются для того, чтобы получить доступ к реальным данным. Например, допустим, что имеется следующий неоднородный массив, который включает в себя десять других массивов, каждый из которых содержит целые значения, являющиеся делителями целых чисел из диапазона от 1 до 10 int[][] divisors1Tol0 = {new int[] {1}, new int [] {1, 2}, new int[] {1, 3}, new int [] {1, 2, 4}, new int[] {1, 5}, new int[] {1, 2, 3, 6}, new int[] {1, 7}, new int [ ] {1, 2, 4, 8}, new int[] {1, 3, 9},
new int[] {1, 2, 5, 10}},
foreach (int divisor in divisors1To10) { | |
Console.WriteLine(divisor); } |
Использование следующего кода является недопустимым, поскольку divisorslTol0 содержит в себе не элементы int, а элементы int [ ] Поэтому нам придется проходить не только по самому массиву, но и непосредственно по каждому субмассиву:
foreach (int[] divisors1To10 in divisors1Tol0) { foreach (int divisor in divisors1To10)
{
Console.WriteLine(divisor); } }
При использовании неоднородных массивов синтаксис очень быстро становится сложным. В большинстве случаев оказывается проще использовать либо прямоугольные массивы, либо какой-нибудь другой, более простой способ хранения данных.
3.2.8.Действия над строками
До сих пор все наши операции над строками сводились к выводу строк на консоль, чтению строк с консоли и объединению строк посредством оператора +. Переменная типа string – это всего лишь массив переменных типа char, доступных в режиме "только чтение". Иными словами, можно получить доступ к отдельным символам строки следующим образом:
string myString = "A string"; |
cnar myChar = myString[l] ; |
Однако присваивать отдельные символы таким способом нельзя.
Для получения массива, доступного для записи, следует воспользоваться приведенным ниже кодом. В нем используется команда ToCharArray () переменной типа массива:
string myString = "A string";
char [ ] myChars = myStrrig.ToCharArray();
Теперь можно выполнять манипуляции с массивом типа char обычным путем. Строки могут использоваться и в циклах foreach:
foreach (char character m myString) {
Console WriteLine("{0}" , character);
}
Как и в случае других массивов имеется возможность узнать число элементов с помощью myString.Length. Таким же образом можно определить общее количество символов в строке:
string myString = Console.ReadLine() ; | |
Console.WriteLine("You typed {0} characters.", myString.Length); |
Другим основополагающим способом работы со строками является использование команд в формате, аналогичном формату команды <string>ToCharArray(). Существуют две простые, но очень полезные команды <stnng>.ToLower() и <string>.ToUpper(). Они позволяют переводить всю строку целиком в нижний и верхний регистр соответственно. Они могут быть использованы, например, в поступлении от пользователя какого-то ответа, например, строки "yes". Если перевести всю введенную строку в нижний регистр, то можно воспринять и такие строки, как "YES", "Yes", "yeS" и т д.
string userResponse = Console.ReadLine() , if (userResponse.ToLower() == "yes") {
// выполнение действий в случае получения ответа }
Эта команда, как и другие рассматриваемые в данной лекции команды, на самом деле не изменяет ту строку, к которой применяется. Напротив, использование этой команды для некоторой строки приводит к созданию новой строки, которую можно сравнить с какой-либо другой строкой (как показано выше) или присвоить другой переменной. В роли этой переменной может выступать переменная, над которой выполняется данная операция:
userResponse = userResponse.ToLower();
Что еще можно сделать для облегчения интерпретации ответов пользователя. Что произойдет в том случае, если пользователь случайно включил в начало или в конец своего ответа пробел. В таком варианте вышеприведенный код не сработает. Необходимо убрать из введенной строки все пробелы, чего можно добиться посредством команды
<string>.Trim().
string userResponse = Console ReadLine(); userResponse = userResponse Trim(); if (userResponse ToLower() = = “yes”) {
// выполнение действий в случае получения ответа. }
В этом случае можно определить строки, подобные следующим: "YES" "Yes".
Такая же команда может быть использована для удаления любых других символов, которые задаются с помощью массива типа char, например:
char[] trimChars ={' ', 'е', 's'};
string userResponse = Console.ReadLine (); userResponse = userResponse.ToLower(); userResponse = userResponse Trim(trimChars); if {userResponse = = "y") {
// выполнение действий в случае получения ответа }
Это позволяет удалить все пробелы, символы "е" и символы "s", находящиеся в начале или в конце строки. Если предположить, что в строке отсутствуют какие-либо другие символы, то появится возможность определять строки: "Yeeeees" " У" и им подобные.
Существует также возможность использовать команды <string>.TrimStart() и <string>.TrimEnd(), которые будут удалять пробелы только из начала или только из конца строки соответственно. В этих командах также имеется возможность задания массива типа char удаляемых символов.
Имеются еще две команды работы со строками, которые выполняют манипуляции с пробелами внутри строк <string>.PadLeft() и <string>.PadRight () эти команды позволяют дополнять строки пробелами слева или справа до заданной длины строки. Они могут использоваться следующим образом:
<string>. PadX (<требуемаяДлина>); Например:
myString = "Aligned"; | |
mуString = myString. PadLeft (10) |
;
В результате к слову "Aligned", содержащемуся в переменной myString, будут добавлены три пробела слева. Этот метод может оказаться полезным для выравнивания строк, располагаемых одна над другой, в частности, при расположении строк с номерами