Посмотрим на следующий пример:
Эти 3 одномерных массива можно представить как двухмерный массив следующим образом:
Давайте посмотрим на другой пример:
Эти 3 одномерных массива нельзя представить как двумерный массив, потому что размеры массивов различаются.
Объявление 2D-массива
тип данных имя-массива[СТРОКА] [COL]
- Тип данных это тип данных элементов массива.
- Имя-массива - это имя массива.
- Два нижних индекса представляют количество строк и столбцов массива. Общее количество элементов массива будет ROW * COL.
int a [2] [3];
Используя приведенный выше код C, мы можем объявить целое число множество, а размера 2 * 3 (2 ряда и 3 столбца).
char b [3] [2];
Используя приведенный выше код C, мы можем объявить персонаж множество, б размера 2 * 3 (3 ряда и 2 столбца).
Инициализация 2D-массива
Мы можем инициализировать во время объявления следующими способами:
- int a [3] [2] = 1,2,3,4,5,6;
- int a [] [2] = 1,2,3,4,5,6;
- int a [3] [2] = 1, 2, 3, 4, 5, 6;
- int a [] [2] = 1, 2, 3, 4, 5, 6;
Обратите внимание, что во 2 и 4 мы не упомянули 1ул нижний индекс. Компилятор C автоматически вычисляет количество строк из количества элементов. Но 2nd должен быть указан подстрочный индекс. Следующие инициализации недействительны:
- int a [3] [] = 1,2,3,4,5,6;
- int a [] [] = 1,2,3,4,5,6;
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 | // Пример1.c #включать #define ROW 3 #define COL 2 int main () int i, j; int a [ROW] [COL] = 1,2, 3,4, 5,6 ; printf ("Построчными элементами массива a являются: \ n"); для (i = 0; i printf ("Строка% d:", i); для (j = 0; j printf ("% d", a [i] [j]); printf ("\ п"); printf ("\ n \ nКолоночные элементы массива a: \ n"); для (i = 0; i printf ("Столбец% d:", i); для (j = 0; j printf ("% d", a [j] [i]); printf ("\ п"); возврат 0; |
В Example1.c, мы объявили целочисленный массив размером 3 * 2 и инициализировали. Для доступа к элементам массива мы используем два цикла for.
Для доступа по строкам внешний цикл предназначен для строк, а внутренний цикл - для столбцов.
Для доступа к столбцам внешний цикл предназначен для столбцов, а внутренний цикл - для строк.
Обратите внимание, что когда мы объявляем 2D-массив, мы используем [2] [3], что означает 2 строки и 3 столбца. Индексация массива начинается с 0. Чтобы получить доступ к 2nd ряд и 3rd столбец, мы должны использовать обозначение a [1] [2].
Отображение памяти 2D-массива
Логическое представление массива а [3] [2] может быть следующим:
Компьютерная память - это одномерная последовательность байтов. На языке C двумерный массив хранится в памяти в рядовой порядок. Некоторые другие языки программирования (e.грамм., FORTRAN), он хранится в порядковый номер столбца в памяти.
Указатель арифметики двумерного массива
Чтобы понять арифметику указателей в 2D-массиве, сначала взгляните на 1D-массив.
Рассмотрим одномерный массив:
В 1D массиве, а - константа, а ее значение - адрес 0th расположение массива а [5]. Значение а + 1 это адрес 1ул расположение массива а [5]. а + я это адрес яth расположение массива.
Если мы увеличим а на 1 он увеличивается на размер типа данных.
а [1] эквивалентно * (а + 1)
а [2] эквивалентно * (а + 2)
а [я] эквивалентно * (а + я)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 год | // Пример2.c #включать #define ROW 3 #define COL 2 int main () int a [5] = 10,20,30,40,50; printf ("sizeof (int):% ld \ n \ n", sizeof (int)); printf ("a:% p \ n", a); printf ("а + 1:% р \ п", а + 1); printf ("a + 2:% p \ n \ n", a + 2); printf ("a [1]:% d, * (a + 1):% d \ n", a [1], * (a + 1)); printf ("a [2]:% d, * (a + 2):% d \ n", a [1], * (a + 1)); printf ("a [3]:% d, * (a + 3):% d \ n", a [1], * (a + 1)); возврат 0; |
В Example2.c, адрес памяти отображается в шестнадцатеричном формате. Разница между a и a + 1 равна 4, что является размером целого числа в байтах.
Теперь рассмотрим 2D-массив:
б указатель типа: int [] [4] или же int (*) [4]
int [] [4] это строка из 4 целых чисел. Если мы увеличиваем b на 1, он увеличивается на размер строки.
б это адрес 0th строка.
б + 1 это адрес 1ул строка.
б + я это адрес яth строка.
Размер строки: (Число столбцов * sizeof (тип данных)) байт
Размер строки целочисленного массива b [3] [4] составляет: 4 * sizeof (int) = 4 * 4 = 16 байт
Строку двумерного массива можно рассматривать как одномерный массив. б это адрес 0th строка. Итак, получаем следующее
- * б + 1 это адрес 1ул элемент 0th
- * b + j это адрес jth элемент 0th
- * (b + i) это адрес 0th элемент яth
- * (b + i) + j это адрес jth элемент яth
- b [0] [0] эквивалентно ** b
- b [0] [1] эквивалентно * (* b + 1)
- b [1] [0] эквивалентно * (* (b + 1))
- b [1] [1] эквивалентно * (* (b + 1) +1)
- b [i] [j] эквивалентно * (* (b + i) + j)
Адрес b [i] [j]: b + sizeof (тип данных) * (Номер столбца * i + j)
Рассмотрим 2D-массив: int b [3] [4]
Адрес b [2] [1]: : b + sizeof (число) * (4 * 2 + 1)
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 | // Example3.c #включать #define ROW 3 #define COL 4 int main () int i, j; int b [ROW] [COL] = 10,20,30,40, 50,60,70,80, 90,100,110,120 ; printf ("sizeof (int):% ld \ n", sizeof (int)); printf ("Размер строки:% ld \ n", COL * sizeof (int)); printf ("b:% p \ n", b); printf ("b + 1:% p \ n", b + 1); printf ("b + 2:% p \ n", b + 2); printf ("* b:% p \ n", * b); printf ("* b + 1:% p \ n", * b + 1); printf ("* b + 2:% p \ n", * b + 2); printf ("b [0] [0]:% d ** b:% d \ n", b [0] [0], ** b); printf ("b [0] [1]:% d * (* b + 1):% d \ n", b [0] [1], * (* b + 1)); printf ("b [0] [2]:% d * (* b + 2):% d \ n", b [0] [2], * (* b + 2)); printf ("b [1] [0]:% d * (* (b + 1)):% d \ n", b [1] [0], * (* (b + 1))); printf ("b [1] [1]:% d * (* (b + 1) +1):% d \ n", b [1] [1], * (* (b + 1) +1) ); возврат 0; |
В Example3.c, мы видели, что размер строки равен 16 в десятичной системе счисления. Разница между b + 1 и b равна 10 в шестнадцатеричной системе счисления. 10 в шестнадцатеричной системе счисления эквивалентно 16 в десятичной системе счисления.
Заключение
Итак, в этой статье мы узнали о
- Объявление 2D-массива
- Инициализация 2D-массива
- Отображение памяти 2D-массива
- Указатель арифметики двумерного массива
Теперь мы можем использовать 2D-массив в нашей программе на C без всяких сомнений,
Рекомендации
Авторы некоторых идей в этой работе вдохновили курс «Указатели и двумерные массивы», подготовленный Палашем Дей, Департамент компьютерных наук и Англии. Индийский технологический институт Харагпур