Массивы в C (часть 2): многомерные массивы

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

[][][][][]
[][][][][]
[][][][][]

В этом примере изображен двумерный массив размером 3*5, 3 — строки и 5 столбцов. Объявление двумерного массива почти ничем не отличается от объявления одномерного, за исключением того, что при объявлении двумерного массива, нужно указывать размер каждого измерения в квадратных скобочках. Например, давайте объявим двумерный массив размером 8*8, это размер поля для стандартных шашек — 8 строк и 8 столбцов:

int checkers[8][8]; // двумерный массив

То есть, двумерный массив хорошо подходит для хранения информации на шашечном поле. Также двумерный массив можно легко использовать для хранения информации о любой другой игре — шахматы, крестики нолики, сапер и т. д. Чтобы получить доступ к любому элементу такого массива, нужно воспользоваться двумя значениями — индексами, первый индекс — это номер строки, а второй — номер столбца. Все выше сказанное относится и к n-мерным массивам. Хотя, уже 4-х мерные массивы сложновато визуализировать. Присваивать значения элементам массива очень просто, вот пример:

// присваиваем первому элементу массива значение - 5
myArray[0] = 5;

Пример присваивания значения элемента двумерного массива:

// присваиваем первому элементу массива значение - 5
myArray[1][3] = 10;

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

[__][__][__][__][__]
[__][__][__][10][__]
[__][__][__][__][__]

Как видите, все просто, главное помните, что нумерация строк и столбцов всегда начинается с 0. То есть, я еще раз хочу вам напомнить, что вы никогда не должны пытаться записать данные после последнего элемента массива, например, когда у вас есть массив размером — 10 элементов и вы пытаетесь присвоить значение элементу с индексом [10]. Память для массива была выделена только для десяти элементов, (индексы от 0 до 9), поэтому элемента с индексом 10 просто не существует. В таком случае, запись в оперативной памяти может привести к непредсказуемым последствиям — например, вы можете в конечном итоге испортить работу параллельно запущенной программы. Однако, как правило, операционная система не позволит такого рода безрассудное поведение и приведет к краху программы, если та попытается получить доступ к нераспределенной памяти.

Давайте рассмотрим практический пример использования массивов в программах:

#include <stdio.h>

int main()
{
  int i, j;
  int myArray[8][8]; // объявляем массив размером 8*8 элементов

  for ( i = 0; i < 8; i++ ) {
    for ( j = 0; j < 8; j++ )
      myArray[i][j] = i * j; // каждому элементу присваиваем значение произведения текущих индексов элемента массива
  }

  printf( "Вот такой массив у нас получился:\n" );
  for ( i = 0; i < 8; i++ ) {
    for ( j = 0; j < 8; j++ )
    {
        printf( "[%d][%d]=%d ", i, j, myArray[i][j] );
    }
    printf( "\n" );
  }
  getchar();
}

Сразу смотрим результат работы программы:

CppStudio.com
Вот такой массив у нас получился:
[0][0]=0 [0][1]=0 [0][2]=0 [0][3]=0 [0][4]=0 [0][5]=0 [0][6]=0 [0][7]=0 
[1][0]=0 [1][1]=1 [1][2]=2 [1][3]=3 [1][4]=4 [1][5]=5 [1][6]=6 [1][7]=7 
[2][0]=0 [2][1]=2 [2][2]=4 [2][3]=6 [2][4]=8 [2][5]=10 [2][6]=12 [2][7]=14 
[3][0]=0 [3][1]=3 [3][2]=6 [3][3]=9 [3][4]=12 [3][5]=15 [3][6]=18 [3][7]=21 
[4][0]=0 [4][1]=4 [4][2]=8 [4][3]=12 [4][4]=16 [4][5]=20 [4][6]=24 [4][7]=28 
[5][0]=0 [5][1]=5 [5][2]=10 [5][3]=15 [5][4]=20 [5][5]=25 [5][6]=30 [5][7]=35 
[6][0]=0 [6][1]=6 [6][2]=12 [6][3]=18 [6][4]=24 [6][5]=30 [6][6]=36 [6][7]=42 
[7][0]=0 [7][1]=7 [7][2]=14 [7][3]=21 [7][4]=28 [7][5]=35 [7][6]=42 [7][7]=49

В этом примере, мы сначала заполняем двумерный массив произведением его индексов, строки 8 — 11. А потом выводим на экран его содержимое, строки 13 — 20.

Если вы хотите объявить указатель на массив, то вы не должны использовать операцию взятия адреса — &, вот пример:

char *ptrArray;
char myString[10];
ptrArray = myString;  // указателю присваиваем адрес первого элемента массива myString без использования &

В то время как с обычными переменными, этого сделать нельзя, пример:

int *ptrNumber;
int number;
ptrNumber = &number; // обязательно используем оператор - &

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

P.S.: После прочтения статьи, рекомендую вам отвлечься от программирования. Хороший способ это сделать — интересная игра. Достаньте смартфон и запустите свою любимую игру. А вот и полезная ссылка для фанатов андроида — скачать игры для андроид. Игр очень много и все интересные, а главное — бесплатные.

Практика

К сожалению, для данной темы пока нет подходящих задач. Если у вас есть таковые на примете, отправте их по адресу: admin@cppstudio.com. Мы их опубликуем!

Автор: Marienko L.
Дата: 06.02.2014
Поделиться:

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.