Г. Шилдт - Полный справочник по C# (1160789), страница 33
Текст из файла (страница 33)
Поскольку каждый массив сопровождается информацией о собственной длине, можно использовать эту информацию, а не вручную отслеживать размер массива. При этом следует иметь в виду, чтосвойство Length никак не связано с реально используемым количеством элементовмассива. Оно содержит количество элементов, которое массив способен хранить.При получении длины многомерного массива возвращается общее количествоэлементов, обусловленное "врожденной" способностью массива хранить данные. Например:// Использование свойства Length для 3-х-мерного массива.using System;class LengthDemo3D {public static void Main() {int[,,] nums = new int[10, 5, 6],Console.WriteLine("Длина массива равна " + nums.Length);Вот результаты выполнения этой программы:1 Длина массива равна 300Как подтверждает результат запуска предыдущей программы, свойство Length содержит количество элементов, которое может хранить массив nums и которое в данном случае равно 300 (10 х 5 х 6).
При этом у нас нет возможности получить длинумассива по конкретному измерению (координате).Использование свойства Length упрощает многие алгоритмы за счет выполненияболее простых операций над массивами. Например, следующая программа используетсвойство Length для реверсирования содержимого массива посредством его копирования в другой массив в направлении от конца к началу.// Реверсирование массива.using System;class RevCopy {public static void Main() {int i,j;int[] numslnew int[10],int[3 nums2new int[10],for(i=0; i < numsl.Length;numsl[i] = i;Console.Write("Исходное содержимое массива: " ) ;for(i=0; i < nums2.Length; i++)Console.Write(numsl[i] + " " ) ;Console.WriteLine();// Копируем массив numsl в массив nums2 с// изменением порядка следования элементов,if (nums2.Length >~ numsl.Length) // Необходимо// убедиться, что массив nums2// достаточно велик.Часть I.
Язык С #for(i=0, j=numsl.Length-1; i < numsl.Length; i++f j — )nums2[j] = numsl[i];Console.Write("Содержимое массива в обратном порядке: " ) ;for(i=0; i < nums2.Length; i++)Console.Write(nums2[i] + " " ) ;Console.WriteLine();•Вот как выглядят результаты выполнения этой программы:Исходное содержимое массива:0 1 2 3 4 5 6 7 8 9Содержимое массива в обратном порядке:9 8 7 6 5 4 3 2 1 0Здесь свойство Length выполняет две важных функции. Во-первых, оно подтверждает, что массив-приемник имеет размер, достаточный для хранения содержимогоисходного массива.
Во-вторых, оно обеспечивает условие завершения цикла for, который выполняет реверсное копирование. Безусловно, это очень простой пример, иразмер массива легко узнать и без свойства Length, но аналогичный подход можноприменить к широкому диапазону более сложных ситуаций.Использование свойства Length при работе с рванымимассивамиПри работе с рваными массивами использование свойства L e n g t h приобретаетособое значение, поскольку позволяет получить длину каждого отдельного ("строчного") массива. Рассмотрим, например, следующую программу, которая имитирует>аботу центрального процессора (ЦП) в сети с четырьмя узлами.// Демонстрация использования свойства Length при// работе с рваными массивами.using System;c l a s s Jagged {p u b l i c s t a t i c v o i d Main() {i n t [ ] [ ] n e t w o r k _ n o d e s = new i n t [ 4 ] [ ] ;n e t w o r k _ n o d e s [ 0 ] = new i n t [ 3 ] ;network__nodes [1] = new i n t [ 7 ] ;network__nodes [2] = new i n t [ 2 ] ;n e t w o r k _ n o d e s [ 3 ] = new i n t [ 5 ] ;inti, j ;// Создаем фиктивные данные по// использованию ЦП.for(i=0; i < network__nodes .Length; i++)for(j=0; j < network_nodes[i].Length; j++)network_nodes [i] [ j ] = i * j + 70,Console.WriteLine ("Общее количество сетевых узлов: " +network_nodes.Length + " \ n " ) ;for(i=0; i < network_nodes.Length;for(j=0; j < network_nodes[i].Length;Глава 7.
Массивы и строки167Console.Write("Ис п о л ь з о в а н и е ЦП на у з л е " + i +11для ЦП " + j + " : " ) ;C o n s o l e . W r i t e ( n e t w o r k _ n o d e s [ i ] [ j ] + "% " ) ;Console.WriteLine();}Console.WriteLine ();Результаты выполнения этой программы выглядят так:Общее количество сетевых узлов: 4Использование ЦП на узле 0 для ЦП 0: 70%Использование ЦП на узле 0 для ЦП 1: 70%Использование ЦП на узле 0 для ЦП 2: 70%ИспользованиеИспользованиеИспользованиеИспользованиеИспользованиеИспользованиеИспользованиеЦП наЦП наЦП наЦП наЦП наЦП наЦП наузлеузлеузлеузлеузлеузлеузле1111111длядлядлядлядляЦП 0: 70%ЦП 1: 71%ЦП 2: 72%ЦП 3: 73%ЦП 4: 74%Д Л Я ЦП 5: 75%для ЦП 6: 76%Использование ЦП на узле 2 для ЦП 0: 70%Использование ЦП на узле 2 для ЦП 1: 72%Использование ЦП на узле 3 для ЦП 0: 70%Использование ЦП на узле 3 для ЦП 1: 73%Использование ЦП на узле 3 для ЦП 2: 7 6%Использование ЦП на узле 3 для ЦП 3: 7 9%Использование ЦП на узле 3 для ЦП 4: 82%Обратите внимание на то, как свойство Length используется для рваного массиваn e t w o r k n o d e s .
Вспомните, что двумерный рваный массив — это массив массивов.Поэтому выражениеI network_nodes.Lengthвозвращает количество массивов, хранимых в массиве network_nodes (в данном случае это значение равно 4). Чтобы получить длину отдельного массива во "внешнем"Иваном массиве, используйте, например, такое выражение:network_nodes[0].LengthЭто выражение возвращает длину первого массива.ЦИКЛ f o r e a c hВ главе 5 упоминалось о том, что в языке С# определен цикл f oreach, но подробное его рассмотрение было отложено на "потом".
По заголовку этого раздела нетрудно догадаться, что время для этого наступило.Цикл foreach используется для опроса элементов коллекции. Коллекция — этогруппа объектов. С# определяет несколько типов коллекций, и одним из них являетсямассив. Формат записи цикла f oreach имеет такой вид:f oreach (тип имя__переменной in коллекция)168инструкция;Часть I. Язык С#Здесь элементы тип и имя_переменной задают тип и имя итерационной переменной, которая при функционировании цикла f о reach будет получать значения элементов из коллекции. Элемент коллекция служит для указания опрашиваемой коллекции (в данном случае в качестве коллекции мы рассматриваем массив).
Таким образом, элемент тип должен совпадать (или быть совместимым) с базовым типоммассива. Здесь важно запомнить, что итерационную переменную применительно кмассиву можно использовать только для чтения. Следовательно, невозможно изменить содержимое массива, присвоив итерационной переменной новое значение.Рассмотрим простой пример использования цикла foreach. Приведенная ниже программа создает массив для хранения целых чисел и присваивает его элементам начальныезначения. Затем она отображает элементы массива, попутно вычисляя их сумму.// Использование цикла foreach.using System;class ForeachDemo {public static void Main() {int sum = 0;int[] nums = new int[10];// Присваиваем элементам массива nums значения,for(int i = 0; i < 10; i++)nums[i] - i;// Используем цикл foreach для отображения значений// элементов массива и их суммирования,foreach(int x in nums) {Console.WriteLine("Значение элемента равно: " + х ) ;sum += х;}Console.WriteLine("Сумма равна: " + sum);При выполнении этой программы получим следующие результаты:Значение элемента равно: 0Значение элемента равно: 1Значение элемента равно: 2Значение элемента равно: 3Значение элемента равно: 4Значение элемента равно: 5Значение элемента равно: бЗначение элемента равно: 7Значение элемента равно: 8Значение элемента равно: 9Сумма равна: 4 5Как видно из приведенных выше результатов, цикл foreach последовательно опрашивает элементы массива в направлении от наименьшего индекса к наибольшему.Несмотря на то что цикл foreach работает до тех пор, пока не будут опрошенывсе элементы массива, существует возможность досрочного его останова с помощьюинструкции break.
Например, следующая программа суммирует только пять первыхэлементов массива nums.I// Использование инструкции break в цикле foreach.using System;Глава 7. Массивы и строки(169class ForeachDemo {public static void Main() {int sum = 0 ;int[] nums = new int[10];// Присваиваем элементам массива nums значения,for(int i = 0; i < 10; i++)nums[i] = i;// Используем цикл foreach для отображения значений// элементов массива и их суммирования,foreach(int x in nums) {Console.WriteLine("Значение элемента равно: " + х) ;sum += х;if(х == 4) break; // Останов цикла, когда х равен 4.}Console.WriteLine("Сумма первых 5 элементов: " + sum);Вот как выглядят результаты выполнения этой программы:Значение элемента равно: 0Значение элемента равно: 1Значение элемента равно: 2Значение элемента равно: 3Значение элемента равно: 4Сумма первых 5 элементов: 10Очевидно, что цикл foreach останавливается после получения пятого элементамассива.Цикл foreach работает и с многомерными массивами.
В этом случае он возвращает элементы в порядке следования строк: от первой до последней.// Использование цикла foreach с двумерным массивом.using System;class ForeachDemo2 {public static void Main() {int sum = 0;int[,] nums = new int[3,5];// Присваиваем элементам массива nums значения„for(int i « 0; i < 3; i++)for(int j=0; j < 5; jnums[i,j] =// Используем цикл foreach для отображения значений// элементов массива и их суммирования,foreach(int x in nums) {Console.WriteLine("Значение элемента равно: " + х)sum += х;}Console.WriteLine("Сумма равна: " + sum);170Часть I. Язык С #Вот результаты выполненияЗначение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Значение элемента равно:Сумма равна: 90этой программы:123452468103691215Поскольку цикл f oreach может опрашивать массив последовательно (от начала кконцу), может сложиться впечатление, что его использование носит весьма ограниченный характер.
Однако это не так. Для функционирования широкого круга алгоритмов требуется именно такой механизм. Одним из них является алгоритм поиска.Например, следующая программа использует цикл f oreach для поиска в массиве заданного значения. Когда значение найдено, цикл останавливается.// Поиск значения в массиве с помощью цикла f o r e a c h .using System;class Search {public static void Main() {int[] nums = new int[10];int val;bool found = false;// Присваиваем элементам массива nums значения,for(int i = 0; i < 10; 2++)nums[i] = i;val = 5;// Используем цикл foreach для поиска в массиве nums// заданного значения.foreach(int x in nums) {if(x == val) {found = true;break;if(found)Console.WriteLine("Значение найдено! ") ;Цикл foreach также используется для вычисления среднего значения, определения минимального или максимально числа в наборе чисел, поиска дубликатов и т.д.Как будет показано далее, цикл foreach особенно полезен при работе с другими типами коллекций.Глава 7.