Как объявляется массив в c. Программирование на языке Си: Использование массивов данных в Си. Указатели

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

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

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

Элемент массива (значение элемента массива) – значение, хранящееся в определенной ячейке памяти, расположенной в пределах массива, а также адрес этой ячейки памяти.
Каждый элемент массива характеризуется тремя величинами:

  • адресом элемента — адресом начальной ячейки памяти, в которой расположен этот элемент;
  • индексом элемента (порядковым номером элемента в массиве);
  • значением элемента.

Адрес массива – адрес начального элемента массива.

Имя массива – идентификатор, используемый для обращения к элементам массива.

Размер массива – количество элементов массива

Размер элемента – количество байт, занимаемых одним элементом массива.

Графически расположение массива в памяти компьютера можно представить в виде непрерывной ленты адресов.

Представленный на рисунке массив содержит q элементов с индексами от 0 до q-1 . Каждый элемент занимает в памяти компьютера k байт, причем расположение элементов в памяти последовательное.

Адреса i -го элемента массива имеет значение

Адрес массива представляет собой адрес начального (нулевого) элемента массива. Для обращения к элементам массива используется порядковый номер (индекс) элемента, начальное значение которого равно 0 . Так, если массив содержит q элементов, то индексы элементов массива меняются в пределах от 0 до q-1 .

Длина массива – количество байт, отводимое в памяти для хранения всех элементов массива.

ДлинаМассива = РазмерЭлемента * КоличествоЭлементов

Для определения размера элемента массива может использоваться функция

int sizeof (тип);

Например,

sizeof (char ) = 1;
sizeof (int ) = 4;
sizeof (float ) = 4;
sizeof (double ) = 8;

Объявление и инициализация массивов

Для объявления массива в языке Си используется следующий синтаксис:

тип имя[размерность]={инициализация};

Инициализация представляет собой набор начальных значений элементов массива, указанных в фигурных скобках, и разделенных запятыми.

int a = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // массив a из 10 целых чисел

Если количество инициализирующих значений, указанных в фигурных скобках, меньше, чем количество элементов массива, указанное в квадратных скобках, то все оставшиеся элементы в массиве (для которых не хватило инициализирующих значений) будут равны нулю. Это свойство удобно использовать для задания нулевых значений всем элементам массива.

int b = {0}; // массив b из 10 элементов, инициализированных 0


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

int a = {1, 2, 3, 4, 5, 6, 7, 8, 9};

При обращении к элементам массива индекс требуемого элемента указывается в квадратных скобках .

Пример на Си

1
2
3
4
5
6
7
8

#include
int main()
{
int a = { 5, 4, 3, 2, 1 }; // массив a содержит 5 элементов
printf("%d %d %d %d %d\n" , a, a, a, a, a);
getchar();
return 0;
}

Результат выполнения программы:

Однако часто требуется задавать значения элементов массива в процессе выполнения программы. При этом используется объявление массива без инициализации. В таком случае указание количества элементов в квадратных скобках обязательно.

int a;

Для задания начальных значений элементов массива очень часто используется параметрический цикл:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


#include
int main()
{
int a;
int i;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]);
}
// Вывод элементов массива
for (i = 0; i<5; i++)
printf("%d " , a[i]); // пробел в формате печати обязателен
getchar(); getchar();
return 0;
}

Результат выполнения программы

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

В языке Си могут быть также объявлены многомерные массивы. Отличие многомерного массива от одномерного состоит в том, что в одномерном массиве положение элемента определяется одним индексом, а в многомерном - несколькими. Примером многомерного массива является матрица.

Общая форма объявления многомерного массива

тип имя[размерность1][размерность2]...[размерностьm];

Элементы многомерного массива располагаются в последовательных ячейках оперативной памяти по возрастанию адресов. В памяти компьютера элементы многомерного массива располагаются подряд, например массив, имеющий 2 строки и 3 столбца,

int a;


будет расположен в памяти следующим образом

Общее количество элементов в приведенном двумерном массиве определится как

КоличествоСтрок * КоличествоСтолбцов = 2 * 3 = 6.

Количество байт памяти, требуемых для размещения массива, определится как

КоличествоЭлементов * РазмерЭлемента = 6 * 4 = 24 байта.

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

Значения элементов многомерного массива, как и в одномерном случае, могут быть заданы константными значениями при объявлении, заключенными в фигурные скобки {} . Однако в этом случае указание количества элементов в строках и столбцах должно быть обязательно указано в квадратных скобках .

Пример на Си

1
2
3
4
5
6
7
8
9

#include
int main()
{
int a = { 1, 2, 3, 4, 5, 6 };
printf("%d %d %d\n" , a, a, a);
getchar();
return 0;
}



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

Пример на Си

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

#define _CRT_SECURE_NO_WARNINGS
#include
int main()
{
int a; // массив из 2 строк и 3 столбцов
int i, j;
// Ввод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("a[%d][%d] = " , i, j);
scanf("%d" , &a[i][j]);
}
}
// Вывод элементов массива
for (i = 0; i<2; i++) // цикл по строкам
{
for (j = 0; j<3; j++) // цикл по столбцам
{
printf("%d " , a[i][j]);
}
printf("\n" ); // перевод на новую строку
}
getchar(); getchar();
return 0;
}



Передача массива в функцию

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

  • адрес массива,
  • размер массива.

Исключение составляют функции обработки строк, в которые достаточно передать только адрес.

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

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

Пример на Си Дан массив из 10 элементов. Поменять местами наибольший и начальный элементы массива. Для операций поиска максимального элемента и обмена использовать функцию.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#define _CRT_SECURE_NO_WARNINGS
#include
// Функция обмена
void change(int *x, int n)
{
// x - указатель на массив (адрес массива)
// n - размер массива
int i;
int max, index;
max = x;
index = 0;
// Поиск максимального элемента
for (i = 1; i {
if (x[i]>max)
{
max = x[i];
index = i;
}
}
// Обмен
x = x;
x = max;
}
// Главная функция
int main()
{
int a;
int i;
for (i = 0; i<10; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]);
}
change(a, 10); // вызов функции обмена
// Вывод элементов массива
for (i = 0; i<10; i++)
printf("%d " , a[i]);
getchar();
getchar();
return
p = p * x[i];
}
return p;
}
// Главная функция
int main()
{
int a; // объявлен массив a из 5 элементов
int i;
int pr;
// Ввод элементов массива
for (i = 0; i<5; i++)
{
printf("a[%d] = " , i);
scanf("%d" , &a[i]); // &a[i] - адрес i-го элемента массива
}
pr = func(a, 5); // вычисление произведения
printf("\n pr = %d" , pr); // вывод произведения четных элементов
getchar(); getchar();
return 0;
}



Массивы

Массив представляет собой совокупность переменных одного типа с общим для обращения к ним именем. В C# массивы могут быть как одномерными, так и многомерными. Массивы служат самым разным целям, поскольку они предоставляют удобные средства для объединения связанных вместе переменных.

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

Для тoго чтобы воспользоваться массивом в программе, требуется двухэтапная процедура, поскольку в C# массивы реализованы в виде объектов. Во-первых, необходимо объявить переменную, которая может обращаться к массиву. И во-вторых, нужно создать экземпляр массива, используя оператор new.

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { // Объявляем массив int myArr = new int; // Инициализируем каждый элемент массива вручную myArr = 100; myArr = 23; myArr = 25; myArr = 31; myArr = 1; foreach (int i in myArr) Console.WriteLine(i); Console.ReadLine(); } } }

Следует иметь в виду, что если массив только объявляется, но явно не инициализируется, каждый его элемент будет установлен в значение, принятое по умолчанию для соответствующего типа данных (например, элементы массива типа bool будут устанавливаться в false, а элементы массива типа int - в 0).

Инициализация массива

Помимо заполнения массива элемент за элементом (как показано в предыдущем примере), можно также заполнять его с использованием специального синтаксиса инициализации массивов. Для этого необходимо перечислить включаемые в массив элементы в фигурных скобках { }. Такой синтаксис удобен при создании массива известного размера, когда нужно быстро задать его начальные значения:

// Синтаксис инициализации массива с использованием // ключевого слова new int myArr = new int {10,20,30,40,50}; // Синтаксис инициализации массива без использования // ключевого слова new string info = { "Фамилия", "Имя", "Отчество" }; // Используем ключевое слово new и желаемый размер char symbol = new char { "X","Y","Z","M" };

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

Ключевое слово var позволяет определить переменную так, чтобы лежащий в ее основе тип выводился компилятором. Аналогичным образом можно также определять неявно типизированные локальные массивы. С использованием такого подхода можно определить новую переменную массива без указания типа элементов, содержащихся в массиве. Давайте рассмотрим пример:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { var arr1 = new { 1, 2, 3 }; Console.WriteLine("Тип массива arr1 - {0}",arr1.GetType()); var arr2 = new { "One", "Two", "Three" }; Console.WriteLine("Тип массива arr2 - {0}",arr2.GetType()); Console.ReadLine(); } } }

Разумеется, как и при создании массива с использованием явного синтаксиса C#, элементы, указываемые в списке инициализации массива, должны обязательно иметь один и тот же базовый тип (т.е. должны все быть int, string или MyCar).

Определение массива объектов

В большинстве случаев при определении массива тип элемента, содержащегося в массиве, указывается явно. Хотя на первый взгляд это выглядит довольно понятно, существует одна важная особенность. В основе каждого типа в системе типов.NET (в том числе фундаментальных типов данных) в конечном итоге лежит базовый класс System.Object . В результате получается, что в случае определения массива объектов находящиеся внутри него элементы могут представлять собой что угодно:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string args) { // Объявляем и инициализируем массив объектов object arrByObject = { true, 10, "Привет", 13.7m }; // Выведем в консоль тип каждого члена массива foreach (object me in arrByObject) Console.WriteLine("Тип {0} - {1}",me,me.GetType()); Console.ReadLine(); } } }

Пожалуйста, приостановите работу AdBlock на этом сайте.

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

Рис.1 Переменные и массивы. Аналогия с коробками.

На картинке выше изображено три массива:

  • целочисленный массив из 8 элементов с именем arr_int
  • вещественный массив из 11 элементов с именем arr_float
  • символьный массив из 6 элементов с именем arr_char

У массива, как и у переменной, имеются свои имя и тип данных. Кроме того, у массива ещё есть одна дополнительная характеристика – размер массива. Размер массива – количество элементов, которые могут в нём храниться. В нашей аналогии с коробочками это количество коробок.

Обратите внимание!

Нумерация элементов массива начинается с нуля, а не с единицы.

Объявление и инициализация массива

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

Листинг 1.

Int arr_int; double arr_float; float number;

На имя массива накладываются ограничения, аналогичные тем, которые накладываются на имя переменной.

Правило именования массивов

Имя массива – любая последовательность символов, цифр и знака нижнего подчеркивания «_», которая начинается с буквы. Регистр букв важен.

Вот ещё несколько примеров объявления массивов:

Листинг 2.

Int grades, order; double prices;

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

Листинг 3.

Int arr_int = {2, 5, 5, 3, 4}; double arr_float = {1.2, -2.3, 4.5, 3.83, 0.01, -0.12, 44.2, 123.7, 23.44, -3.7, 7};

Если нужно присвоить нулевые значения всем элементам массива, то можно сделать вот так:

Листинг 4.

Double arr = {0};

Работа с отдельными элементами массива

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

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

Листинг 5.

#include int main(void){ int arr = {2, 4, 3, 5, 5}; printf("%d %d %d %d %d\n",arr, arr, arr, arr, arr); return(0); }

Конечно, если массив будет очень большой, то выводить его поэлементно подобным образом то ещё удовольствие. Да и с маленькими массивами так никто не делает. Лучше и правильнее использовать циклы. Например:

Листинг 6.

#include int main(void){ int arr = {0}; for(int i = 0; i < 100; i = i + 1){ arr[i] = 2*i; } for(int i = 0; i < 100; i = i + 1){ printf("%d\t",arr[i]); } return(0); }

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

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

Листинг 7.

#include #include #include int main(void) { srand(time(NULL)); int count = {0}; int rand_number; for (int i = 0; i < 100000; i = i + 1){ rand_number = rand()%3; count = count + 1; } for(int i = 0; i < 3; i = i + 1){ printf("%d - %d\n", i, count[i]); } return 0; }

Обратите внимание на приём, который используется в этой программе.
В нулевом элементе массива хранится количество выпадений числа 0 , в первом элементе – количество выпадений числа 1 , во втором элементе – числа 2 . То есть само сгенерированное число позволяет определить, к какому элементу массива необходимо добавить единичку. Поэтому необходимость в операторе выбора switch отпадает. Удобно, не так ли?

Продолжаем изучение основ C++. В этой статье мы рассмотрим массивы.

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

Введение в массивы

Визуализировать массив можно следующим образом:

Это набор некоторых значений, которые хранятся друг за другом, под одним именем. Для получения этих значений вам не придется создавать новых переменных, нужно только указать индекс под которым хранится значение в массиве. Например, вам необходимо раздать набор из пяти игральных карт для покера, вы можете хранить эти карты в массиве и для выбора новой карты изменять только номер индекса, вместо использования новой переменной. Это позволит использовать один и тот же код для инициализации всех карт и перейти от такой записи:

Card1 = getRandomCard(); Card2 = getRandomCard(); Card3 = getRandomCard(); Card4 = getRandomCard(); Card5 = getRandomCard();

For (int i = 0; i < 5; i++) { card[i] = getRandomCard(); }

А теперь представьте разницу, если переменных 100!

Синтаксис

Для объявления массива необходимо указать две вещи (помимо имени): тип и размер массива:

Int my_array[ 6 ];

Данная строка объявляет массив из шести целочисленных значений. Обратите внимание, что размер массива заключен в квадратные скобки после имени массива.

Для доступа к элементам массива используются квадратные скобки, но на этот раз вы указываете индекс элемента, который хотите получить:

My_array[ 3 ];

Визуализировать данный процесс можно так:


my_array ссылается на весь массив целиком, в то время как my_array только на первый элемент, my_array — на четвертый. Обратите внимание, что индексация элементов в массиве начинается с 0. Таким образом Обращение к элементам массива всегда будет происходить со смещением, например:

Int my_array[ 4 ]; // объявление массива my_array[ 2 ] = 2; // установить значение третьего (именно третьего!) равным 2

Объявление многомерных массивов в C++

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

Для объявления двумерного массива необходимо указать размерность двух измерений:

Int tic_tac_toe_board;

Визуализация массива с индексами его элементов:

Для доступа к элементам такого массива потребуется два индекса — один для строки второй для столбца. На изображении показаны нужные индексы для доступа к каждому из элементов.

Использование массивов

При использовании массивов вам не обойтись без . Для того, чтобы пробежать по циклу вы просто инициализируете нулевую переменную и увеличиваете её, пока она не превысит размеры массива — шаблон как раз подходящий для цикла.

Следующая программа демонстрирует использование цикла для создания таблицы умножения и хранения результата в двумерном массиве:

#include using namespace std; int main() { int array; // Объявляем массив, который выглядит как шахматная доска for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { array[i][j] = i * j; // Задаем значения каждого элемента } } cout << "Multiplication table:\n"; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { cout << "[ " << i << " ][ " << j << "] = "; cout << array[i][j] << " "; cout << "\n"; } } }

Передаем массивы в функции

Как видите, разные элементы языка C++ взаимодействуют друг с другом. Как и с циклами, массивы можно использовать вместе с .

Чтобы передать массив в функцию достаточно просто указать его имя:

Int values[ 10 ]; sum_array(values);

А при объявлении функции указать массив в качестве аргумента:

Int sum_array (int values);

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

Так как внутри функции мы не знаем размер массива, необходимо передать размерность в качестве второго аргумента:

Int sumArray(int values, int size) { int sum = 0; for (int i = 0; i < size; i++) { sum += values[ i ]; } return sum; }

Когда мы передаем многомерные массивы, надо указывать все размерности, за исключением первой:

Int check_tic_tac_toe (int board);

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

Подробнее эта тема будет раскрыта в статье про указатели.

А пока напишем функцию, которая вычисляет сумму элементов массива:

#include using namespace std; int sumArray(int values, int size) { int sum = 0; // цикл остановится когда i == size, потому что индекс последнего элемента = size - 1 for (int i = 0; i < size; i++) { sum += values[i]; } return sum; } int main() { int values; for (int i = 0; i < 10; i++) { cout << "Enter value " << i << ": "; cin >> values[i]; } cout << sumArray(values, 10) << endl; }

Сортировка массива

Решим задачу сортировки массива из 100 чисел, которые ввел пользователь:

#include using namespace std; int main() { int values[ 100 ]; for (int i = 0; i < 100; i++) { cout << "Enter value " << i << ": "; cin >> values[ i ]; } }

Готово, осталось только отсортировать этот массив 🙂 Как обычно люди сортируют массивы? Они ищут самый маленький элемент в нем и ставят его в начало списка. Затем они ищут следующее минимальное значение и ставят его сразу после первого и т.д.

Все это дело выглядит как цикл: пробегаем по массиву, начиная с первого элемента и ищем минимальное значение в оставшейся части, и меняем местами эти элементы. Начнем с написания кода для выполнения этих операций:

Void sort(int array, int size) { for (int i = 0; i < size; i++) { int index = findSmallestRemainingElement(array, size, i); swap(array, i, index); } }

Теперь можно подумать о реализации двух вспомогательных методов findSmallestRemainingElement и swap. Метод findSmallestRemainingElement должен пробегать по массиву и находить минимальный элемент, начиная с индекса i:

Int findSmallestRemainingElement(int array, int size, int index) { int index_of_smallest_value = index; for (int i = index + 1; i < size; i++) { if (array[ i ] < array[ index_of_smallest_value ]) { index_of_smallest_value = I; } } return index_of_smallest_value; }

Наконец, нам надо реализовать функцию swap. Так как функция изменит оригинальный массив, нам просто надо поменять значения местами, используя временную переменную:

Void swap(int array, int first_index, int second_index) { int temp = array[ first_index ]; array[ first_index ] = array[ second_index ]; array[ second_index ] = temp; }

Для проверки алгоритма заполним массив случайными числами и отсортируем. Весь код программы:

#include #include #include using namespace std; int findSmallestRemainingElement(int array, int size, int index); void swap(int array, int first_index, int second_index); void sort(int array, int size) { for (int i = 0; i < size; i++) { int index = findSmallestRemainingElement(array, size, i); swap(array, i, index); } } int findSmallestRemainingElement(int array, int size, int index) { int index_of_smallest_value = index; for (int i = index + 1; i < size; i++) { if (array[ i ] < array[ index_of_smallest_value ]) { index_of_smallest_value = i; } } return index_of_smallest_value; } void swap(int array, int first_index, int second_index) { int temp = array[ first_index ]; array[ first_index ] = array[ second_index ]; array[ second_index ] = temp; } // вспомогательная функция для вывода массива void displayArray(int array, int size) { cout << "{"; for (int i = 0; i < size; i++) { // если элемент не первый выведем запятую if (i != 0) { cout << ", "; } cout << array[ i ]; } cout << "}"; } int main() { int array[ 10 ]; srand(time(NULL)); for (int i = 0; i < 10; i++) { array[ i ] = rand() % 100; } cout << "Original array: "; displayArray(array, 10); cout << "\n"; sort(array, 10); cout << "Sorted array: "; displayArray(array, 10); cout << "\n"; }

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

Еще одним видом массивов C# являются массивы массивов, называемые также изрезанными массивами (jagged arrays). Такой массив массивов можно рассматривать как одномерный массив, элементы которого являются массивами, элементы которых, в свою очередь, снова могут быть массивами, и так может продолжаться до некоторого уровня вложенности.

В каких ситуациях может возникать необходимость в таких структурах данных? Эти массивы могут применяться для представления деревьев, у которых узлы могут иметь произвольное число потомков. Таковым может быть, например, генеалогическое дерево. Вершины первого уровня -Fathers , представляющие отцов, могут задаваться одномерным массивом, так что Fathers [ i ] - этоi -й отец. Вершины второго уровня представляются массивом массивов -Children , так чтоChildren [ i ] - это массив детейi -го отца, аChildren [ i ][ j ] - это j-й ребенокi -го отца. Для представления внуков понадобится третий уровень, так чтоGrandChildren [ i ][ j ][ k ] будет представлять к -го внукаj -го ребенка i -го отца.

Есть некоторые особенности в объявлении и инициализации таких массивов. Если при объявлении типа многомерных массивов для указания размерности использовались запятые, то для изрезанных массивов применяется более ясная символика - совокупности пар квадратных скобок; например, int [ ] задает массив, элементы которого - одномерные массивы элементов типа int .

Сложнее с созданием самих массивов и их инициализацией. Здесь нельзя вызвать конструкторnew int , поскольку он не задает изрезанный массив. Фактически нужно вызывать конструктор для каждого массива на самом нижнем уровне. В этом и состоит сложность объявления таких массивов. Начнем с формального примера:

//массив массивов - формальный пример
//объявление и инициализация
int [ ] jagger = new int [ ] {
new int[ ] {5, 7, 9, 11},
new int[ ] {2, 8},
new int[ ] {6, 12, 4}
};

Массивjagger имеет всего два уровня. Можно считать, что у него три элемента, каждый из которых является массивом. Для каждого такого массива необходимо вызвать конструкторnew , чтобы создать внутренний массив. В данном примере элементы внутренних массивов получают значение, будучи явно инициализированы константными массивами. Конечно, допустимо и такое объявление:

int [ ] jagger 1 = new int [ ] {
new int ,
new int ,
new int
};

В этом случае элементы массива получат при инициализации нулевые значения. Реальную инициализацию нужно будет выполнять программным путем. Стоит заметить, что в конструкторе верхнего уровня константу 3 можно опустить и писать простоnew int [ ] . Вызов этого конструктора можно вообще опустить - он будет подразумеваться:

int [ ] jagger 2 = {
new int,
new int,
new int
};

А вот конструкторы нижнего уровня необходимы. Еще одно важное замечание - динамические массивы возможны и здесь. В общем случае, границы на любом уровне могут быть выражениями, зависящими от переменных. Более того, допустимо, чтобы массивы на нижнем уровне были многомерными.