Как инициализировать двумерный массив c
Перейти к содержимому

Как инициализировать двумерный массив c

  • автор:

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

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

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

Например, двумерный массив

int a[2][3];
int a[3][4][5];

Доступ до элементов массива осуществляется также, как и в одномерном массиве

#include #include #define SIZE 5 void main() < int M[3][3]; unsigned i, j; for (i = 0; i < 3; i++) < for (j = 0; j < 3; j++) < M[i][j] = i * j; >> do < printf("enter indexes:\n"); scanf("%d", &i); scanf("%d", &j); if (i < 3 && j < 3) < printf("M[%d][%d] == %d\n", i, j, M[i][j]); >else < break; >> while (1); for (i = 0; i < 3; i++) < for (j = 0; j < 3; j++) < printf("\t%d", M[i][j]); >printf("\n"); > getch(); >

Особенностью является то, что по своему строению многомерный массив является обыкновенным, «одномерным», массивом. Все элементы расположены друг за другом. Доступ до элемента a[i][j] – по существу сдвиг на i*число столбцов + j. В двумерном массиве, таким образом, элементы расположены «по рядам», в трёхмерном — «по слоям», внутри которых элементы расположены «по рядам» и т.д.
В связи с этим, при начальной инициализации опускать размерность можно только в первых квадратных скобках:

int a[][3] = ; int b[][5][25] = ;

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

int a[2][3] = ;

Можно опустить первую размерность

int a[][2][3] = ;

Можно с помощью фигурных скобок сделать данные более удобными для чтения

int a[2][3] = {{1, 2, 3>, 
int a[][3][4] = {{{1, 2, 3, 4>, , , , , , 

Также, как и в одномерных массивах, если заявлено данных больше, чем указано при инициализации, то оставшиеся заполняются нулями. Например, единичная матрица 3 на 3

int zero3[3][3] = {{1>, , 

Из того, что многомерный массив является одномерным по структуре, вытекают некоторые интересные свойства. Например, доступ до элемента может быть осуществлён через его порядковый номер
a[i][j] === a[0][i*число столбцов + j] и т.д.

Примеры

1. Отсортируем двумерный массив методом пузырька. Для сортировки обычно используется два подхода - превращение двумерного массива в одномерный, сортировка, обратно превращение одномерного в двумерный, либо запутанное обращение к элементам через индекс. Можно сделать всё проще: работать с многомерным массивом как с одномерным

#include #include #define ROWS 4 #define COLS 3 void main() < int a[ROWS][COLS] = {{1, 4, 5>, , , > > while(flag); for (i = 0; i < ROWS; i++) < for (j = 0; j < COLS; j++) < printf("%3d", a[i][j]); >printf("\n"); > _getch(); >

Замечание: по стандарту явно такое поведение не определено, но косвенно должно поддерживаться.

2. Даны координаты x и y точки, полученные в ходе фотосъёмки. Известно, сколько кадров в секунду делала камера. Вычислить скорость в каждый момент времени и среднюю скорость за всё время.

#include #include #include #define SIZE 10 void main() < float a[2][SIZE] = {{1.03, 1.52, 2.11, 2.53, 3.08, 3.48, 3.98, 4.51, 5.02, 5.17>, speed /= (float)(SIZE - 1); for (i = 1; i < SIZE; i++) < printf("v[%d] = %.3f m/s\n", i, velocity[i-1]); >printf("mean velocity = %.3f", speed); _getch(); >

3. Массив используется как карта, где число 2 означает начало, а 3 - конец пути. Программа сначала находит координаты этих точек, после этого вычисляет расстояние Манхеттена (сколько нужно пройти по x и y от начала до конца) и расстояние по Евклиду (как гипотенузу прямоугольного треугольника).

#include #include #include #define SIZE 5 #define START 2 #define FINISH 3 void main() < char field[SIZE][SIZE] = < , , , , >; unsigned i, j; unsigned x, y; char xFound = 0; int X, Y; char XFound = 0; unsigned manhattanDist; float euclidDist; for (i = 0; i < SIZE; i++) < for (j = 0; j < SIZE; j++) < if (field[i][j] == START) < x = i; y = j; xFound = 1; if (XFound) < break; >> if (field[i][j] == FINISH) < X = i; Y = j; XFound = 1; if (xFound) < break; >> > if (xFound && XFound) < break; >> if (!(xFound && XFound)) < printf("Error: corrupted data\n"); getch(); exit(1); >printf("(x,y) = %d, %d\n(X,Y)= %d, %d\n", x, y, X, Y); manhattanDist = abs((int)(x-X)) + abs((int)(y-Y)); //тоже самое, что и sqrt((x-X)*(x-X)+(y-Y)*(y-Y)) x -= X; y -= Y; euclidDist = sqrt((float)(x*x + y*y)); printf("Manhattan dist. = %d\nEuclid dist. = %.3f", manhattanDist, euclidDist); getch(); >

4. Пользователь вводит 10 слов. Вывести слово с максимальной длиной. Программа внешне совершенно простая, единственная проблема - считывание и вывод слова. Так как слова храняться в двумерном массиве, то указатель на words[i][0] - это начало нового слова. Также не забываем об ограничении на длину при вводе.

#include #include #define SIZE 10 #define MAX_LENGTH 128 void main() < //Массив хранит 10 слов максимум по 128 символов char words[SIZE][MAX_LENGTH]; unsigned i, j, maxLength; //Так как длина слова ограничена 127 символами, то типа char хватит unsigned char counter[SIZE]; for (i = 0; i < SIZE; i++) < //Считываем слова. words[i][0] - это символ, нам нужен //адрес, начиная с которого можно писать в массив fgets(&words[i][0], MAX_LENGTH - 1, stdin); j = 0; //Считаем длину слова while (words[i][j]) < j++; >counter[i] = j; > //Ищем слово с максимальной длиной maxLength = counter[0]; j = 0; for (i = 1; i < SIZE; i++) < if (counter[i] >maxLength) < maxLength = counter[i]; j = i; >> //Выводим слово на печать. При выводе строки //необходимо передавать указатель printf("%s", &words[j][0]); _getch(); >

ru-Cyrl 18- tutorial Sypachev S.S. 1989-04-14 sypachev_s_s@mail.ru Stepan Sypachev students

email

Всё ещё не понятно? – пиши вопросы на ящик

Инициализировать многомерные массивы в C

В этом посте мы обсудим, как инициализировать многомерные массивы на языке программирования C.

Многомерный массив — это массив с более чем одним измерением. Простейшим многомерным массивом является двумерный массив или двумерный массив. Это в основном массив массивов, который также широко известен как матрица. Общий синтаксис инициализации массива применим и к многомерным массивам.

1. Использование статического хранилища

Все объекты в C со статической продолжительностью хранения устанавливаются равными 0, которые не были явно инициализированы программистом. Следующий код инициализирует первую ячейку 6 × 8 матрицу в 0, а остальные элементы как если бы они имели статическую продолжительность хранения, т.е. инициализировались нулем.

Инициализация двумерного динамического массива

@VTT а почему? Что происходит во вторым? Почему даже значение элемента второго элемента нельзя получить?

8 ноя 2019 в 20:25

Видимо вы рассчитывали на то, что new int[n] < 0 >будет вызываться для каждого элемента, однако все, кроме первого, будут инициализироваться нулями.

8 ноя 2019 в 20:26

@VTT массивами то они должны, по идее, остаться, даже если они инициализированы нулями. Или в двумерном массиве ссылки (ну или указатели) на одномерные хранятся?

8 ноя 2019 в 20:28

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

При инициализации массива с указанным размером отсутствующие инициализаторы - нули. Т.е.

int a[5] = ; 

заполняет массив a значениями 6,0,0,0,0.

Заметим - инициализация значением, а не вычислением выражения 🙂

int i = 0; int a[5] = ; 

не будет применять i++ ко всем элементам массива.

new int* [n] < new int[n] < 0 >>; 

? Вычисляется единственное значение new int[n] < 0 >, присваивается первому элементу массива. Остальные заполняются нулями. Дальнейшее понятно? 🙂

Если вы хотите использовать именно C++, а не некий мутированный C, то vector вам в руки:

vector> ints(n, vector(n,0)); 

И никаких забот с освобождением памяти 🙂

Update

По дополненному вопросу - при полном отсутствии инициализатора как такового никакая инициализация не выполняется, и массив в результате заполнен мусором.

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

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

спецификатор типа имя_массива [размерN] . [размер1] = ;

Список значений - это разделенный запятыми список констант, совместимых по типу со спецификатором типа. Первая константа помещается в первый элемент массива, вторая - во второй и так далее. За последней константой списка нет запятой. Обратим внимание, что точка с запятой следует за >. В следующем примере 10-элементный целочисленный массив инициализируется числами от 1 до 10:

Это означает, что i[0] получит значение 1, i[9] - 10.

Массивы символов, содержащие строки, допускают удобную инициализацию в виде

char имя_массива [размер] = "строка";

При данной инициализации нулевой терминатор автоматически добавляется к концу строки. Нижеприведенный фрагмент кода инициализирует строку str фразой «hello»:

char str[6] = "hello";

Это можно также записать:

Обратим внимание, что в данной версии следует явным образом указать нулевой символ. Поскольку все строки в С оканчиваются нулевым символом, следует убедиться, что массив достаточно длинный для его вмещения. Именно поэтому str состоит из 6 символов, хотя «hello» имеет только 5 символов.

Многомерные массивы инициализируются так же, как и одномерные. Следующий пример инициализирует sqrs числами от 1 до 10 и их квадратами:

Здесь sqrs[0][0] содержит 1, sqrs[0][1] содержит 1, sqrs[1][0] содержит 2, sqrs[1][1] содержит 4 и так далее.

При инициализации многомерных массивов можно добавить фигурные скобки вокруг каждого измерения. Это так называемая субагрегатная группировка. Ниже приведен еще один способ записи предыдущего объявления:

При использовании субагрегатной группировки в случае неуказания требуемого количества инициализаторов для данной группы остальные члены установятся в 0 автоматически.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *