Урок 5: «Массивы»

Если предыдущие уроки носили скорее вводный характер, то на этом уже нужно акцентировать внимание. Массивы и циклы играют важную роль при программировании на любом языке. Поэтому старайтесь внимать и запоминать то, что здесь будет написано. Для начала вызубрите определение массива. Массив – это структура данных, представляющая собой набор элементов одного типа, имеющий общее имя. Понятно? Думаю, что навряд ли. К сожалению, многие термины в информатике носят несколько запутанный характер, однако вдумавшись в это определение, вы все поймете сами. Давайте я разберу популярным языком, что такое массивы и для чего они были придуманы. Представьте себе задачу, в которой нам нужно создать список из 20 сотрудников, который мы потом должны вывести либо в файл, либо на печать ( и то, и другое мы скоро разберем). Итак, как мы будем решать эту задачу? Логично будет предположить, что для каждого имени сотрудника нужно будет зарезервировать место в памяти, или, говоря иначе, выделить отдельную переменную. Давайте так и поступим. Будем давать этим переменным осмысленные имена, соответствующие настоящим ФИО сотрудников этого списка: string ivanov=”Иванов”; string petrov=”Петров”; string sidorov=”Сидоров”; … string yablokov=”Яблоков”; Все, список создан в памяти и теперь мы можем выводить каждое имя на консоль (повторю, это всего лишь вариант, как неправильно делать): cout<<ivanov<<endl <<petrov<<endl <<sidorov<<endl; //Я выведу всего три имени. Казалось бы, ничего нет проще – каждому имени переменной соответствует реальное имя сотрудника. Задача выполнена. Однако теперь несколько усложним ее. Представьте себе, что ваш знакомый оценил эту программу и решил использовать ее у себя. Вот только у него в подчинении 25 сотрудников. Естественно, писать ее придется именно вам. Вы решаете использовать тот же способ и кое-как делаете задачу. А если нужно 2500 сотрудников? Бьюсь об заклад, что вы утомитесь придумывать только имена переменным. Кроме того, этот список не обладает никакой функциональностью. Его практически невозможно отсортировать и сложно будет найти нужное имя в списке. Именно поэтому в таких целях используются массивы. Теперь давайте применим массив на практике. Мы уже поняли, что писать каждое уникальное имя переменной глупо. Гораздо проще написать абстрактное имя sort, прибавляя к ней единицу: string sotr1; string sotr2; Иными словами, у нас уже подразумевается в задаче набор данных в виде списка строк с именами. И имя у этого набора будет как раз sotr. Вот мы и вплотную подошли к объявлению массива. А он объявляется так: тип_данных общее_имя [размерность массива]; В нашем случае это будет выглядеть так: string sotr [20]; // массив из двадцати строк Подобно тому, как мы прибавляли 1 к имени sotr, для доступа к элементу массива используется индекс. Он всегда числовой! sotr[0]=”Иванов”; sotr[19]=”Яблоков”; Теперь в нашем списке двадцать строк с именами. Постойте, мы указали размерность 20, а последний элемент носит индекс 19. А где же еще один элемент? В C++, как и в C (и во многих других языках) нумерация массива начинается с 0. Поэтому последний элемент всегда будет равен размер -1 Подсчитайте сами: int array [5]={1,2,3,4,5}; Я сейчас объявил массив чисел с именем array и срузу же инициализировал его. Для этого используются фигурные скобки. Это тоже самое, что и: int array [5]; array [0]=1; … array[4]=5; Как видите, этот способ более компактен. Инициализировать массив нужно только тогда, когда требует логика программы. Мы могли сделать так и с нашим списком сотрудников: string sotr [20]={“Иванов”,”Петров”,”Сидоров”,…”Яблоков”}; Многотичие писать вам ненужно, если вы вдруг решили повторить мой код. Я просто таким образом опускаю список. Кстати, часто при использовании массива требуется инициализировать его. Мы можем забить все элементы числового массива нулями таким образом: int array [100]={0}; // все 100 элементов равны 0. Я уже упоминал, что строка – это массив символов, оканчивающийся нулевым символом (он выглядит так – ‘\0’), который является признаком конца строки. Иными словами, строка в сишной нотации вводится так: char ivanov []=”Иванов”; // в массиве сейчас 7 символов, 7-Й –нулевой символ Учтите, что размер массива здесь можно опустить только в случае инициализации при объявлении. Иначе нам нужно указывать размер, как мы делали раньше. С таким массивом крайне неудобно работать, особенно тем, кто перешел на C++ с других языков. Поэтому здесь был введен класс string, находящийся в заголовочном файле <string> (варианты могут быть — <string.h>, <cstring>). Этот тот же массив символов, но только оформлен уже в виде класса. Пока запомните это до того, как мы изучим объектно-ориентированное программирование. В С++ остался существенный недостаток от С – он не проверяет выход индекса за размеры массива. Это значит, что мы можем легко обратиться к sotr[21] и присвоить ему какое-либо значение. Компилятор радостно все скомпилирует, а вот что будет в программе – одному Богу известно. Поэтому, чтобы не ошибиться используются константные объявления размера массива: const short size=20; string sotr [size]; Не пугайте типа short – это просто короткое целое число. Точно так же используется длинное целое long, которое может хранить большое число. Кстати, в уроке 4 я опустил одни момент – чтобы компилятор не умничал и не приводил большое число к типу double, при объявлении long нужно ставить суффикс l: long value=235453235l; // явно указываем, что это long. Вернемся к нашим массивам. Удобство константы вы поймете на примере работы с циклами. Завершить тему массив хотелось бы несколькими моментами. Массивы, которые мы создавали хранятся в стеке, а, значит, ограничены его размером. Что такое стек вы вскоре узнаете. Однако могу сказать, что слишком большой массив компилятор просто не даст вам скомпилировать, а если даже программа запустится, произойдет так называемое переполнение стека, радость для любого хакера. Чтобы этого избежать, используются динамические массивы. Мы пока не будем их затрагивать, оставив их уроку о динамических типах данных. Массив, который мы использовали для хранения списка сотрудников не эффективен, хотя и действенен. Часто возникает ситуация, что в программе список будет постоянно нарастать. Допустим, у вас пока 5 сотрудников, а через год их может быть 50. Выделять массив под 5 сотрудников – глупо, так как его придется наращивать. Под 50 — еще глупее, так как расходуется память под хранение пока еще не заполненных массивов. А ведь этих 45 дополнительных сотрудников может и не быть. В этом случае целесообразнее использовать динамическую структуру данных под названием список (List). Он позволяет нам сделать то, что я описывал –динамически добавлять новые элементы. Причем размер списка будет расти с каждым добавленным элементом. Тем не менее, преимуществ у массива все же больше. Я уже упоминал, что в программах часто придется сортировать данные и находить элементы. Все это удобно как раз делать с помощью массивов. Как это делать, я покажу в уроках по алгоритмике. В С++ были введены удобные ассоциативные массивы. Пока мы их рассматривать тоже не будем, оставив уже на более высокий ваш уровень подготовки. Могу сказать, что в ряде случаев он очень удобен. Еще один важный момент — все рассмотренные нами массивы были одномерными. В C++ имеется возможность создавать и многомерные массивы. По своему опыту могу сказать, что часто используется только двумерный массив. int array [10][10]; //двумерный массив, представляющий собой таблицу 10х10 Для того, чтобы обратиться к элементу массива, мы указываем его номер строки (допустим, 2) и номер столбца (допустим, 4) этой таблицы. Элемент на пересечении этой строки и столбца будет нашим (вспомните хотя бы как вы искали значение в таблице умножения –принцип тот же самый) array [4][2]=34; Точно так же считываются данные из такого массива. Если нужно создать трехмерный массив, то нужно сделать так : int array [10] [10 [10]; И так по аналогии. Инициализируются многомерные массивы так же, как и одномерные: int a [2] [3]= { {1,2}, {2,4,122}}// строки и столбцы разделяются через запятую Кстати, иногда полезно узнать длину массива. Эта величина нам нужна будет, например, в циклах, о которых мы поговорим в уроке 6. int a[]={2,4,5,76,3,2,5}; //Нам лень считать размер, пусть этим займется компьютер int len =sizeof (a) / sizeof (a[0]); Данное выражение вернет нам размер массива. Кто не понял, поясню – мы берем размер всего массива в байтах и делим его на размер в байтах первого элемента массива. Полученное в результате деления число и будет нашей длиной массива. Ну вот, мы разобрали с вами одну из самых сложны для начинающих программистов тем. Если вы не все поняли, советую прочитать все сначала. Я сознательно сделал этот урок о массивах раньше, чем о циклах. Однако благодаря этому вы теперь поймете многие приемы, которые я буду использовать в следующем уроке. А пока отдохните и приготовьтесь к уроку 6: «Циклы». Там будет все гораздо легче.

Вячеслав «VeGA» Головлев

 

<<Предыдущий урок                                                       Следующий урок>>

Яндекс.Метрика