C++.Бархатный путь

       

Основные свойства массивов


Всё, что здесь обсуждается, имеет, прежде всего, отношение к версии языка Borland C++ 4.5. Однако маловероятно, что в других версиях языка массив обладает принципиально другими свойствами.

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

В модулях многомодульной программы массив определяется в одном из модулей (в главном модуле) программы. В остальных модулях при объявлении этого массива используется спецификатор extern. Подобное объявление может быть включено и в главный модуль. Главное, чтобы транслятор мог различить объявления и собственно определение.

В объявлениях со спецификатором extern можно указывать произвольные размеры объявляемого массива (лишь бы они были описаны в виде константного выражения), а можно их и не указывать вовсе - транслятор всё равно их не читает.

int intArray1[10] = {0,1,2,3,4,5,6,7,8,9}; extern intArray1[]; extern intArray1[1000]; /*Казалось бы, если транслятор всё равно не читает значение константного выражения в объявлении, то почему бы там не записать выражение, содержащее переменные?*/ int ArrVal = 99; extern intArray1[ArrVal + 1]; /*Однако этого сделать нельзя. ArrVal не константное выражение.*/

Но зато он очень строго следит за попытками повторной инициализации.

extern intArray1[10] = {9,9,9,}; /*Здесь будет зафиксирована ошибка. Хотя, если в объявлении не проверяется размерность массива, то какой смысл реагировать на инициализацию…*/

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

char chArray_1[6]; char chArray_2[] = {'q', 'w', 'e', 'r', 't', 'y'}; Попытка использовать оператор присвоения вида chArray_1 = chArray_2;


вызывает сообщение об ошибке, суть которой сводится к уведомлению, что выражение chArray_1 не является леводопустимым выражением.

Следует заметить, что подобным образом ведёт себя и константный указатель, с которым мы познакомились раньше. Он также требует немедленной инициализации (это его единственный шанс получить определённое значение) и не допускает последующего изменения собственного значения.

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

По аналогичной причине невозможна и операция присвоения, операндами которой являются имена массивов.

Операторы

intArray1 = intArray2; intArray1[] = intArray2[];

не допускаются транслятором исключительно по той причине, что имя массива аналогично константному указателю. Оно является неизменяемым l-выражением, следовательно, не является леводопустимым выражением и не может располагаться слева от операции присвоения.

Заметим, что при создании в динамической памяти с помощью выражения размещения безымянных массивов объектов (при инициализации указателей на массивы) инициализаторы не допускаются. Инициализатор в выражении размещения может проинициализировать только один объект. И дело здесь не в особых свойствах выражения размещения, а в особенностях языка и самого процесса трансляции.

Рассмотрим процессы, происходящие при выполнении оператора определения массива. Они во многом аналогичны процессам, происходящим при определении константного указателя:


    по константному выражению в описателе или на основе информации в инициализаторе определяется размер необходимой области памяти. Здесь сразу уже необходима полная информация о размерности массива. Размер области памяти составляет равняется произведению размера элемента массива на размерность массива, выделяется память, адрес выделенной области памяти присваивается объекту, который по своим характеристикам близок константному указателю (хотя это объект совершенно особого типа).


Теперь можно вспомнить объявление, которое было рассмотрено нами в одном из прошлых разделов. Объявление массива int intArray_7[];

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


Содержание раздела