|
|||||||||||||||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Многомерные массивыДекларация многомерного массива имеет следующий формат: тип ID [ размер 1][ размер 2]…[ размерN ] = { { список начальных значений }, { список начальных значений }, … }; Списки начальных значений – атрибут необязательный. Наиболее быстро изменяется последний индекс элементов массива, поскольку многомерные массивы в языке Си размещаются в памяти компьютера построчно друг за другом (см. следующую тему «Адресная функция»). Рассмотрим особенности работы с многомерными массивами на конкретном примере двухмерного массива. Например, пусть приведена следующая декларация двухмерного массива: int m [3][4]; Идентификатор двухмерного массива – это указатель на массив указателей (переменная типа указатель на указатель: int ** m;). Поэтому двухмерный массив m [3][4]; компилятор рассматривает как массив трех указателей, каждый из которых указывает на начало массива со значениями размером по четыре элемента каждый. В ОП данный массив будет расположен следующим образом:
(А) (В) Рис. 10.1. Схема размещения элементов массива m размером 3×4
Причем в данном случае указатель m [1] будет иметь адрес m [0]+4* sizeof (int), т.е. каждый первый элемент следующей строки располагается за последним элементом предыдущей строки. Приведем пример программы конструирования массива массивов: #include <stdio.h> void main() { int x0[4] = { 1, 2, 3,4}; // Декларация и инициализация int x1[4] = {11,12,13,14}; // одномерных массивов int x2[4] = {21,22,23,24}; int *m[3] = {x0, x1, x2,}; // Создание массива указателей int i,j; for (i=0; i<3; i++) { printf("\n Cтрока %d) ", i+1); for (j=0; j<4; j++) printf("%3d", m[ i ] [ j ]); } }
Результаты работы программы: Cтрока 1) 1 2 3 4 Cтрока 2) 11 12 13 14 Cтрока 3) 21 22 23 24
Такие же результаты будут получены и в следующей программе: #include <stdio.h> void main() { int i, j; int m[3][4] = { { 1, 2, 3, 4}, {11,12,13,14}, {21,22,23,24} }; for (i=0; i<3; i++) { printf("\n %2d)", i+1); for (j=0; j<4; j++) printf(" %3d",m[ i ] [ j ]); } } В последней программе массив указателей на соответствующие массивы элементов создается компилятором автоматически, т.е. данные массива располагаются в памяти последовательно по строкам, что является основанием для декларации массива m в виде int m[3][4] = {1, 2, 3, 4, 11, 12, 13, 14, 21, 22, 23, 24}; Замена скобочного выражения m [3][4] на m [12] здесь не допускается, так как массив указателей не будет создан. Таким образом, использование многомерных массивов в языке Си связано с расходами памяти на создание массивов указателей. Очевидна и схема размещения такого массива в памяти – последовательное (друг за другом) размещение «строк» – одномерных массивов со значениями (векторная организация памяти). Обращению к элементам массива при помощи операции индексации m [ i ][ j ] соответствует эквивалентное выражение, использующее адресную арифметику – *(*(m + i)+ j). Аналогичным образом можно установить соответствие между указателями и массивами с произвольным числом измерений.
Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.004 сек.) |