Массивы в С++
Производные типы данных: указатель, ссылка, массив, функция. Синтаксис объявления. Описание, примеры объявления и определения массивов, основные свойства. Выражение и l-выражение – доступ к объектам и функциям. Значения констант и функций в C++.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | реферат |
Язык | русский |
Дата добавления | 28.10.2010 |
Размер файла | 20,1 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Массивы в С++
1. Производные типы данных
Производные типы
* - указатель;
& - ссылка;
[ ] - массив;
( ) - функция;
получаются из стандартных типов или классов с помощью операций объявления (их еще называют модификаторами типа).
Массив -- это последовательная группа ячеек памяти, имеющих одинаковое имя и одинаковый тип.
Массив в С++ - это последовательность элементов одного и того же типа.
Доступ к каждому элементу осуществляется по его положению в массиве. Эта форма называется индексацией.
Описание массива состоит из спецификации типа, идентификатора и размерности:
Спецификация типа Идентификатор (имя массива)
int a [ 10 ];
Размерность
Размерность массива должна быть больше или равна 1.
В программе можно обращаться как к массиву целиком (по его имени), так и к отдельным компонентам (элементам) массива. Например,
int i = 123;
a[2] = i;
i = a[7];
Значение размерности должно быть константным выражением, т.е. она должна быть известна на этапе трансляции. Это означает, что переменная не может использоваться (как в Паскале) для задания размерности массива.
2. Массивы. Синтаксис объявления
Массивы представляют собой производные типы (указатели также относятся к производным типам).
Объект типа "массив элементов заданного типа" представляет последовательность объектов этого самого типа, объединенных одним общим именем. Количество элементов массива является важной характеристикой самого массива, но не самого типа. Эта характеристика называется размерностью массива.
Приведем примеры объявления и определения массивов.
extern int intArray_1[];
Объявлен (именно объявлен - об этом говорит спецификатор extern) массив типа int, имя массива - intArray_1, разделители [] указывают на то, что перед нами объявление массива.
int intArray_2[10];
А это уже определение массива. Все тот же тип int, имя массива - intArray, между разделителями [ и ] находится константное выражение, значение которого определяет размерность массива.
Требование синтаксиса по поводу константного выражения между разделителями в определении массива может быть объяснено лишь тем, что информация о количестве элементов массива требуется до момента начала выполнения программы.
int intArray_3[] = {1,2,3}; // Это также определение массива.
Количество элементов массива становится известным транслятору при анализе инициализатора. Элементам массива присваиваются соответствующие значения из списка инициализаторов.
Еще одна форма определения массива:
int intArray_4[3] = {1,2,3};
В этом определении массива важно, чтобы количество элементов в инициализаторе массива не превышало значение константного выражения в описателе массива.
В результате выполнения этого оператора в памяти выделяется область, достаточная для размещения трех объектов-представителей типа int. Участку присваивается имя intArray_4. Элементы инициализируются значениями, входящими в состав инициализатора.
Возможна частичная инициализация массива. При этом значения получают первые элементы массива:
int intArray_5[3] = {1,2};
В этом определении массива означены лишь первые два элемента массива. Значение последнего элемента массива в общем случае не определено.
Здесь нужно отметить одну интересную особенность синтаксиса инициализатора массива. Речь идет о необязательной запятой в конце списка инициализаторов. По-видимому, еT назначение заключается в том, чтобы указывать на факт частичной инициализации массива.
Действительно, последний вариант (частично) инициализирующего оператора определения массива выглядит нагляднее:
int intArray_5[3] = {1,2,};
Последняя запятая предупреждает о факте частичной инициализации массива. Затраты на связывание запятой в конце списка инициализаторов со строго определенным контекстом частичной инициализации оказываются столь значительными, что последняя запятая традиционно (по крайней мере со времени выхода "Справочного руководства по языку программирования C++") оказывается всего лишь необязательным элементом любой (в том числе и полной) инициализации.
int intArray_6[3] = {1,2,3};
int intArray_6[3] = {1,2,3,};// Полная инициализация с запятой
int intArray_6[] = {1,2,3};
int intArray_6[] = {1,2,3,};
Между этими операторами не существует никакой разницы.
А вот в таком контексте
int intArray_6[3] = {1,2,}; // Частичная инициализация массива из трех элементов
Последняя запятая в фигурных скобках - не более как полезное украшение. Что-то недосказанное таится в таком операторе присвоения.
int intArray_7[];
А вот это некорректное объявление. Без спецификатора extern транслятор воспринимает это как ошибку. В скором времени мы обсудим причину этого явления.
3. Основные свойства массивов
Первое специфическое свойство массивов заключается в том, что определение массива предполагает обязательное указание его размеров. Зафиксировать размер массива можно различными способами (о них мы уже говорили), однако это необходимо сделать непосредственно в момент его объявления, в соответствующем операторе объявления.
В модулях многомодульной программы массив определяется в одном из модулей (в главном модуле) программы. В остальных модулях при объявлении этого массива используется спецификатор 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 не является леводопустимым выражением.
4. Выражение и l-выражение
Доступ к объектам и функциям обеспечивается выражениями, которые в этом случае ссылаются на объекты.
Выражение, которое обеспечивает ссылку на константу, переменную или функцию, называется l-выражением. Имя объекта в C++ является частным случаем l-выражения.
В C++ допускается изменение значений переменных. Значения констант и функций в C++ изменению не подлежат. l-выражение называется модифицируемым l-выражением, либо леводопустимым выражением, если только оно не ссылается на функцию, массив или константу. Таким образом, леводопустимыми выражениями называют l-выражения, которые ссылаются на переменные.
Следует заметить, что подобным образом ведет себя и константный указатель, с которым мы познакомились раньше. Он также требует немедленной инициализации (это его единственный шанс получить определенное значение) и не допускает последующего изменения собственного значения.
Часто указатель один "знает" место расположения участка памяти, выделенного операциями или функциями распределения памяти. Изменение значения этого указателя приводит к потере ссылки на расположенный в динамической памяти объект. Это означает, что соответствующая область памяти на все оставшееся время выполнения программы оказывается недоступной.
По аналогичной причине невозможна и операция присвоения, операндами которой являются имена массивов.
Операторы
intArray1 = intArray2;
intArray1[] = intArray2[];
не допускаются транслятором исключительно по той причине, что имя массива аналогично константному указателю. Оно является неизменяемым l-выражением, следовательно, не является леводопустимым выражением и не может располагаться слева от операции присвоения.
Массив символов (типа char) можно инициализировать и списком из отдельных символьных констант, так и строкой символов. При этом в случае строки символов массив получит в конце и нулевой символ, ограничивающий строку, например:
char ca_1 [ ] = { `C', `+', `+' } ;
char ca_2 [ ] = “C++” ;
Здесь са_1 будет размерности 3, а са_2 - размерности 4 и содержать { `C', `+', `+', `\0' }.
Один массив не может инициализироваться другим массивом и не может быть присвоен другому массиву, например:
int a1 [ ] = { 0, 1, 2 } ;
int a2 [ ] = a1 ; // ошибка!!!
. . .
int a3 [ 3 ] ;
a3 = a1 ; // ошибка!!!
Чтобы скопировать один массив в другой, необходимо скопировать каждый элемент по очереди, например:
const int a_size = 7 ;
int a1 [ ] = { 0, 1, 2, 3, 4, 5, 6 } ;
…..
int a2 [ a_size ] ;
for ( int i =0; i < a_size; i++)
a2[ i ] = a1 [ i ] ;
В качестве индекса массива может использоваться любое выражение, которое приводит к целочисленному значению.
В С++ нет контроля выхода за границы массива. Вся ответственность лежит на программисте!
Заметим, что при создании в динамической памяти с помощью выражения размещения безымянных массивов объектов (при инициализации указателей на массивы) инициализаторы не допускаются. Инициализатор в выражении размещения может проинициализировать только один объект. И дело здесь не в особых свойствах выражения размещения, а в особенностях языка и самого процесса трансляции.
Рассмотрим процессы, происходящие при выполнении оператора определения массива. Они во многом аналогичны процессам, происходящим при определении константного указателя:
· по константному выражению в описателе или на основе информации в инициализаторе определяется размер необходимой области памяти. Здесь сразу уже необходима полная информация о размерности массива. Размер области памяти равняется произведению размера элемента массива на размерность массива,
· выделяется память,
· адрес выделенной области памяти присваивается объекту, который по своим характеристикам близок константному указателю (хотя это объект совершенно особого типа).
Теперь можно вспомнить объявление, которое было рассмотрено нами в одном из прошлых разделов. Объявление массива
int intArray_7[];
воспринимается транслятором как ошибочное объявление исключительно по причине функционального сходства между объявлением массива и объявлением константного указателя. Массив, как и константный указатель должен быть проинициализирован в момент объявления.
5. Массив констант
Как уже известно, имя массива является константным указателем. Именно поэтому и невозможно копирование массивов с помощью простого оператора присвоения. Константный указатель "охраняет" область памяти, выделенную для размещения данного массива. При этом значения элементов массива можно изменять в ходе выполнения программы. Защитить их от изменения можно с помощью дополнительного спецификатора типа const. При этом массив должен быть проинициализирован непосредственно в момент определения:
const int cIntArray[] = {0,1,2,3,4,5,6,7,8,9};
Это аналог константного указателя на массив констант. Попытки изменения значения элементов массива пресекаются на этапе компиляции.
cIntArray[5] = 111; // Ошибка.
А вот от скрытого изменения значения элементы массива констант уберечь не удается.
const char cCH[] = "0123456789";
char CH[] = "0123456789";
CH[15] = 'X';
/* Выполнение этого оператора ведет к изменению строки cCH. */
cout << cCH << endl;
Транслятор не занимается проверкой корректности выполняемых операций. На этапе выполнения программы язык C++ не предоставляет никаких средств защиты данных.
Подобные документы
Разработка программ на языке Turbo Pascal на основе использования массивов данных. Особенности хранения данных, способы объявления переменных, действия над элементами массивов, их ввод и вывод. Практическое применение одномерных и многомерных массивов.
методичка [17,8 K], добавлен 25.11.2010Широкое использование компьютерных и информационных технологий. Концепции типов данных. Алгоритмы сортировки одномерных массивов. Описание двумерного массива Паскаля. Методы доступа к элементам массивов. Индексные, динамические и гетерогенные массивы.
курсовая работа [66,3 K], добавлен 07.12.2010Ознакомление с понятием, особенностями объявления, инициализацией и принципами работы с одномерными и двумерными массивами. Изучение смысла тернарной операции вывода элементов матрицы. Рассмотрение сущности и способов использования указателей переменных.
лабораторная работа [22,1 K], добавлен 15.07.2010Сущность понятия "тип данных". Объектно-ориентированный стиль программирования. Простые типы данных в языке Паскаль: порядковые, вещественные, дата-время. Булевский (логический) тип. Синтаксис определения ограниченного типа. Регулярные типы (массивы).
реферат [24,1 K], добавлен 01.12.2009Заголовки процедур и функций, их основные параметры. Работа с массивами и строками в среде разработки Borland Delphi. Основное назначение процедурных типов, правила их объявления. Механизм передачи процедур в качестве фактических параметров вызова.
курсовая работа [27,9 K], добавлен 18.05.2011Понятие массива и правила описания массивов в программах на языке С. Рассмотрение основных алгоритмов обработки одномерных массивов. Примеры программ на языке С для всех рассмотренных алгоритмов. Примеры решения задач по обработке одномерных массивов.
учебное пособие [1,1 M], добавлен 22.02.2011Линейный массив в программе на C++ - упорядоченный набор однотипных переменных, располагающихся в памяти последовательно. Массив как простейшая структура данных, облегчающая работу с большими объемами информации. Использование типизированных констант.
лабораторная работа [33,5 K], добавлен 15.07.2009Способы ограждения пользователей от деталей фактического устройства данных. Список описателей переменных, указателей или массивов. Статические или динамические структуры данных. Доступ к различным элементам данных. Добавление и удаление элементов.
презентация [57,8 K], добавлен 14.10.2013Изучение определения, описания и вызова функций, указателей и ссылок на них. Написание функции умножения произвольного столбца двумерного массива на const. Умножение 2 столбцов массива на константы. Составление блок-схемы алгоритма и текста программы.
лабораторная работа [182,3 K], добавлен 09.01.2012Изучение понятия и основных видов массивов. Ввод массива с клавиатуры и вывод на экран. Сортировка массивов. Метод простых обменов (пузырьковая сортировка). Сортировка простым выбором и простым включением. Решение задач с использованием массивов Паскаля.
курсовая работа [82,1 K], добавлен 18.03.2013