Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3_1 ВУМИ ЛабРабота 1.DOC
Скачиваний:
2
Добавлен:
01.03.2025
Размер:
445 Кб
Скачать
☆

Int array [2] [3];

Последнему элементу массива по умолчанию присваивается значение «/0»:

CHAR S[ ] = “Это массив” /* Данный массив будет представлять собой 11-эдементов, последний из который будет иметь значение «/0».

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

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

Особенности операций с массивами.

1. Если количество инициализаторов меньше, чем объявлено элементов массива явным образом, то всем неопределенным элементам справа на лево по умолчанию присваивается значение 0:

INT ARRAY [2] [3] = { {1, 2} {4} }; /*Получим следующее:

1 2 0

4 0 0

2. Если количество инициализаторов превосходит число элементов массива, то генерируется ошибка.

3. Если инициализирующая строка символов окажется длиннее явным образом определенной длины массива, то лишние символы справа на лево отбрасываются, вместе с символом «/0»:

CHAR S [ 5 ] = “Это массив” /* Последний элемент, с индексом равным четырем, будет иметь значение «м».

4. Если в объекте типа данных UNION (смесь) имеется массива, то при объявлении первый элемент массива обязательно должен быть инициализирован.

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

При обращении к i- элементу массива не через его адрес действует следующий алгоритм:

а). Сначала i умножается на размер типа данных массива, таким образом вычисляется величина смещения относительно начала массива:

I * sizeof (Тип-Данных)

б). Затем определяется новый адрес, когда величина смещения складывается с адресом первого элемента массива:

Новый-Адрес = Базовый-Адрес + i * SIZEOF (Тип-Данных)

Базовый адрес – это адрес первого элемента массива, который выделяет компилятор при объявлении массива.

в). В заключение производится операция разадресации:

* Новый-Адрес

Пример распечатки массива с помощью указателей:

…

INT ARRAY [20]; /* Выделена память

INT *p, l = 10;

VOID Print (INT *, INT); /* Объявление прототипа функции, та как ее

/* определение находится ниже, после точки вызова

…

Print (p, l); /* Вызов функции печати

…

VOID Print (INT * K, INT M)

{

INT * R = M; WHILE ((R – K) >= 0)

{ COUT < *K; K++;

RETURN; }

}

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

Двухмерную матрицу, которая представляет собой массив массива, состоящую из элементов типа FLOAT можно объявить следующим образом:

FLOAT ** MATRIX;

По сущности языка С++ это означает, что массив содержит элементы, которые в свою очередь являются массивами.

Базовый язык С не позволяет использовать обобщенные динамические массивы. Динамическое распределение памяти используется для экономии вычислительных ресурсов и написание более гибких программ.

Тут есть несколько вариантов решений.

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

INT SUM ( INT A[], INT M)

{ INT I, S =0;

FOR ( I = 0; I < N; ++I)

S += A [I];

RETURN (S);

}

Второе. На практике допускается использование следующей абстракции:

STRUCT My_Type

{ DOUBLE * * My_Base; INT Row_Size, Column_Size; }

Указатель My_Base представляет собой указатель на указатель DOUBLE. Основной указатель содержит начальный адрес массива указателей, а каждый указатель - начальный адрес строки, состоящей из DOUBLE.

My_Base

0

0

1

2

Column_Size-1

1

0

1

2

Column_Size-1

0

1

2

Column_Size-1

Column_Size-1

Рис. 1. Распределение адресов оперативной памяти под элементы двухмерного массива

Поэтому для работы с динамическими массивами целесообразно использовать особую память – «кучу»(HEAP) - и одноместные операторы NEW и DELETE, которые заменили устаревшие стандартные библиотечные функции MALLOC, CALLOC, FREE.

Упрощенно размещение информации при выполнении программы можно представить в виде:

Стек

Хранит локальные объекты, определенные внутри функции

Запоминает точки прерывания программы

Сегмент данных

Хранит STATIC и EXTERN объекты, то есть внешние по отношению к функции

Сегмент программного кода

Хранит исполняемый код программы

Куча

Оставшаяся свободная память HEAP

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

Тип-Данных * Имя-Массива = NEW Тип-Данных [Размер];

Пример

VOID ALLOCATE (INT R, INT S, My_Type & M)

{

M.My_Base = NEW DOUBLE *[S]; /* Определено количество строк

FOR (INT i = 0; I < S; ++I)

M.My_Base [ I ] = NEW DOUBLE [R]; /* Выделена память под строки

M.Row_Size = R;

M.Column_Size = S; /* Теперь можно работать

/* с элементами матрицы My_Base

}

Оператор DELETE возвращает память. Его можно выполнять только к объектам, распределенным с помощью оператора NEW. Формат:

DELETE Имя-Объекта;

DELETE [ ] Имя-Массива;

Форма со скобками напоминает, что соответствующее распределение было массивом.

VOID DEALLOCATE (y_Type & M)

{

FOR (INT I =0; I < M.Column_Size; ++I)

DELETE [].My_Base [I];

DELETE [] M.My_Base;

M.Row_Size = 0;

M.Column_Size = 0;

}

Модули ALLOCATE() и DEALLOCAT() – это функции управления свободно памятью.

Для использования библиотечных функций MALLOC(), CALLOC(), REALLOC() и FREE() необходимо подключение с помощью указания препроцессору двух заголовочных файлов <ALLOC.H> и <STDLIB.H>. Это устаревший подход и в новых оболочках типа Builder C++ он не применяется.

Выделением памяти вышеперечисленными функциями производится по следующему формату: