Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Лекция 7. Массивы
Массив - ограниченная совокупность однотипных данных. Элементы массива имеют одно и то же имя, а различаются порядковым номером индексом.
В языке С# массив относится к ссылочным типам данных, то есть располагается только в динамической памяти, поэтому создание массива начинается с выделения памяти под его элементы. Всем элементам при создании массива присваиваются значения по умолчанию нули для значимых типов, и null для ссылочных.
Количество элементов в массиве (размерность) не является частью его типа, это количество задается при выделении памяти и не может быть изменено.
Элементы массива нумеруются с нуля. Для обращения к элементу массива после имени массива указывается номер (индекс) элемента в квадратных скобках.
Массивы одного типа можно присваивать друг другу.
Все массивы в С# имеют общий базовый класс Array, определенный в пространстве имен System.
Одномерные массивы
Одномерные массивы описываются одним из способов:
тип[] имя;
тип[] имя = new тип [размерность];
тип[] имя = {инициализаторы};
тип[] имя = new тип []{инициализаторы};
тип[] имя = new тип [размерность]{инициализаторы};
Примеры описания одномерных массивов:
int [] a; //элементов нет
int [] b=new int [4]; //элементы равны 0
int [] c={1,2,3,4}; //new подразумевается
int [] d=new int[] {1,2,3,4}; //размерность вычисляется
int [] e=new int [4] {1,2,3,4}; //избыточное описание
Для массива а описана ссылка на массив, а память под элементы не выделена (массив не создан).
Массив b будет содержать 4 элемента, которые по умолчанию равны 0.
Для массива с опущен оператор выделения памяти new, который подразумевается по умолчанию.
Для массива d не задана размерность, но он инициализирован, поэтому размерность количество элементов вычисляется.
Для массива е указана и размерность и элементы инициализированы, размерность - константа!
Пример выполнения операций с одномерным массивом
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();
int s=0,k=0;
for (int i=0;i<n;++i)
if (a[i]<0)
{
s+=a[i];
++k;
}
Console.WriteLine(“Сумма отрицательных ”+s);
Console.WriteLine(“Количество отрицательных ”+k);
}}}
Прямоугольные массивы
Прямоугольный массив имеет более одного измерения. В чем особенность объявления многомерного (прямоугольного) массива? Как в типе указать размерность массива? Это делается достаточно просто, за счет использования запятых.
Объявление многомерного массива в общем случае:
<тип>[, ... ,] <идентификаторы>;
Число запятых, увеличенное на единицу, и задает размерность массива.
Примеры описания двумерных массивов:
int [,] a; //элементов нет
int [,] b=new int [2,3]; //элементы равны 0
int [,] c={{1,2,3},{4,5,6}}; //new подразумевается
int [,] d=new int[,]{{1,2,3},{4,5,6}}; //размерность вычисляется
int [,] e=new int [2,3] {{1,2,3},{4,5,6}}; //избыточное описание
Если список инициализации не задан, размерности могут быть не только константами, но и выражениями типа, приводимого к целому.
К элементу двумерного массива обращаются, указывая номер строки и столбца, на пересечении которых он расположен:
a[1,4] - элемент второй строки и пятого столбца!
b[i,j] - элемент i-ой строки и j-ого столбца!
Пример выполнения операций с двумерным массивом
using System;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
const int m=3,n=3;
int [,] a= new int[m,n]
{
{1,1,1},
{0,0,0},
{3,3,3}
};
int [,] b= new int[m,n]
{
{1,2,3},
{4,5,6},
{7,8,9}
};
int [,] c= new int[m,n];
Console.WriteLine(“Исходный массив a: ”);
for (int i=0;i<m;++i)
{
for (int j=0;j<n;++j)
Console.Write(“\t” +a[i,j]);
Console.WriteLine();
}
Console.WriteLine(“Исходный массив b: ”);
for (int i=0;i<m;++i)
{
for (int j=0;j<n;++j)
Console.Write(“\t” +b[i,j]);
Console.WriteLine();
}
for(int i = 0; i < m; ++i)
for(int j = 0; j < n; ++j)
{
int s=0;
for(int k = 0; k < n;++k)
s+= a[i,k]*b[k,j];
c[i,j] = s;
}
Console.WriteLine(“Полученное произведение матриц : ”);
for (int i=0;i<m;++i)
{
for (int j=0;j<n;++j)
Console.Write(“\t” +с[i,j]);
Console.WriteLine();
}
}}}
Все массивы в С# построены на основе базового класса Array, который содержит свойства и методы, представленные в таблице 7.1
Таблица 7.1 Основные элементы класса Array (представлены не полностью)
Свойство |
Описание |
|
Length |
Количество элементов массива (по всем размерностям) |
|
Rank |
Количество размерностей массива |
|
BinarySearch |
Двоичный поиск в отсортированном массиве |
|
Clear |
Выполняет начальную инициализацию элементов. В зависимости от типа элементов устанавливает значение 0 для арифметического типа, false - для логического типа, Null для ссылок, "" - для строк. |
|
Copy |
Копирование части или всего массива в другой массив. |
|
IndexOf |
Поиск индекса первого вхождения элемента в одномерный массив. |
|
LastIndexOf |
Поиск индекса последнего вхождения элемента в одномерный массив. |
|
Reverse |
Изменение порядка следования элементов на обратный. |
|
Sort |
Сортировка элементов одномерного массива |
|
CopyTo |
Копируются все элементы одномерного массива в другой одномерный массив, начиная с заданного индекса |
|
GetLength |
Возвращает число элементов массива по указанному измерению. |
|
GetValue, SetValue |
Возвращает или устанавливает значение элемента массива с указанными индексами. |
Свойство Length позволяет реализовывать алгоритмы, которые будут работать с массивами различной длины. Использование этого свойства вместо явного задания размерности исключает возможность выхода индекса за границы массива.
Пример применения элементов класса Array для работы с одномерным массивом.
using System;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
int [] a= {3,12,5,18,-9,8,-4};
PrintArray (“Исходный массив:”, a); //пользовательская функция (метод)
Console.WriteLine(Array.IndexOf(a,18);
Array.Sort(a);
PrintArray (“Отсортированный массив:”, a);
Console.WriteLine(Array.BinarySearch(a,18));
}//конец Main()
public static void PrintArray(string s, int[] a)
{
Console.WriteLine(s);
for (int i=0;i<a.Length;++i)
Console.Write(“\t”+a[i]);
Console.WriteLine();
} //конец функции
}//конец класса Class1
}//конец пространства имен ConsoleApplication1
Методы Sort(), IndexOf(), BinarySearch() являются статическими, поэтому к ним обращаются через имя класса и передают в них имя массива. Двоичный поиск можно применять только для упорядоченных массивов.
В приведенном примере поиск элемента со значением 18 выполняется двумя способами.
Статический метод PrintArray() предназначен для вывода массива на экран. В него передаются два параметра строка и одномерный массив. Количество элементов массива определяется с помощью свойства Length, поэтому этот метод можно использовать для вывода любого целочисленного одномерного массива.
Для того, чтобы метод PrintArray() мог применяться к массивам другого типа необходимо вместо передачи обычного одномерного массива использовать класс Array. Значения элементов такого массива получают с помощью метода GetValue, так как доступ по индексу для класса Array не предусмотрен.
Модифицированный метод PrintArray
public static void PrintArray(string s, Array a)
{
Console.WriteLine(s);
for (int i=0;i<a.Length;++i)
Console.Write(“\t”+a.GetValue(i));
Console.WriteLine();
}
Оператор foreach для работы с массивами
Оператор foreach применяется для перебора элементов в специальным образом организованной группе данных. Массив является такой группой. Удобство такого вида цикла заключается в том, что не требуется определять количество элементов и выполнять их перебор по индексу. Просто указывается необходимость перебора всех элементов группы. Синтаксис оператора:
foreach (тип имя in выражение) тело_цикла
Имя задает локальную по отношению к циклу переменную, которая будет по очереди принимать все значения из массива выражение (обычно имя массива или имя другой группы данных). В теле цикла выполняются действия с переменной цикла.
Вывод массива a на экран с помощью оператора foreach:
// х - локальная переменная цикла, а - одномерный массив
foreach (int x in a) Console.WriteLine(x);
На каждом проходе цикла очередной элемент массива присваивается переменной х и с ней выполняются действия, записанные в теле цикла.
Пример работы с одномерным массивом с использованием цикла foreach
using System;
namespace ConsoleApplication1
{
class Class1
{
static void Main()
{
const int n=6;
int [] a= {3,12,5,-9,8,-4};
Console.WriteLine(“Исходный массив: ”);
foreach (int x in a)
Console.Write(“\t” +x);
Console.WriteLine();
int s=0,k=0;
foreach (int x in a)
if (x<0)
{
s+=x;
++k;
}
Console.WriteLine(“Сумма отрицательных ”+s);
Console.WriteLine(“Количество отрицательных ”+k);
}}}
Модифицированный метод PrintArray() с использованием оператора цикла foreach
public static void PrintArray(string s, Array a)
{
Console.WriteLine(s);
foreach (object x in a)
Console.Write(“\t”+x);
Console.WriteLine();
}
Такая запись становится возможной потому, что любой объект может быть неявно преобразован к типу базового класса object.
Ограничением применения оператора foreach является то, что с помощью его можно только просматривать значения в группе данных, но не изменять их.
Использование оператора foreach для вывода на экран двумерного массива имеет вид:
foreach (int [] x in a)
{
foreach (int y in x) Console.Write(“\t”+y);
Console.WriteLine();
}
Примеры обработки массивов с использованием класса Array
//ОДНОМЕРНЫЙ МАССИВ
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("Введите размерность массива: ");
int n=Convert.ToInt32(Console.ReadLine());
int[] a = new int[n];
ВводМассива(a);
РешениеЗадачи(a);
ВыводМассива(a);
Console.ReadKey();
}
//----------------------------------------------------------------
public static void ВводМассива(Array a)
{
for (int i = 0; i < a.Length; ++i)
{
Console.Write("Введите {0} элемент массива: ", i + 1);
a.SetValue(Convert.ToInt32(Console.ReadLine()),i);
}
Console.WriteLine("******************************************");
}
//----------------------------------------------------------------
public static void РешениеЗадачи(Array a)
{
for (int i = 0; i < a.Length; ++i)
{
//обработка массива решение задачи
}
}
//----------------------------------------------------------------
public static void ВыводМассива(Array a)
{
Console.WriteLine("Вывод массива: ");
foreach (object x in a)
Console.Write(" "+x);
}
}
}
//ДВУМЕРНЫЙ МАССИВ
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.Write("Введите количество строк массива: ");
int n=Convert.ToInt32(Console.ReadLine());
Console.Write("Введите количество столбцов массива: ");
int m=Convert.ToInt32(Console.ReadLine());
int[,] a = new int[n,m];
ВводМассива(a);
РешениеЗадачи(a);
ВыводМассива(a);
Console.ReadKey();
}
//----------------------------------------------------------------
public static void ВводМассива(Array a)
{
for (int i = 0; i < a.GetLength(0); ++i)
for (int j = 0; i < a.GetLength(1); ++i)
a.SetValue(Convert.ToInt32(Console.ReadLine()),i,j);
}
//----------------------------------------------------------------
public static void РешениеЗадачи(Array a)
{
for (int i = 0; i < a.GetLength(0); ++i)
for (int j = 0; i < a.GetLength(1); ++i)
{
//обработка массива решение задачи
}
}
//----------------------------------------------------------------
public static void ВыводМассива(Array a)
{
// 1 способ
Console.WriteLine("Вывод массива: ");
for (int i = 0; i < a.GetLength(0); ++i)
{
for (int j = 0; i < a.GetLength(1); ++i)
Console.Write(“\t” +a[i,j]);
Console.WriteLine();
{
// 2 способ
Console.WriteLine("Вывод массива: ");
foreach (int [] x in a)
{
foreach (int y in x)
Console.Write("\t "+y);
Console.WriteLine();
}
}
} }}