Использование признака завершения строки



 

Факт завершения нулевыми символами всех С++‑строк можно использовать для упрощения различных операций над ними. Следующий пример позволяет убедиться в том, насколько простой код требуется для замены всех символов строки их прописными эквивалентами.

 

 

Эта программа при выполнении выведет на экран слово TEST . Здесь используется библиотечная функция toupper() , которая возвращает прописной эквивалент своего символьного аргумента. Для вызова функции toupper() необходимо включить в программу заголовок <cctype> .

Обратите внимание на то, что в качестве условия завершения цикла for используется массив str , индексируемый управляющей переменной i (str[i] ). Такой способ управления циклом вполне приемлем, поскольку за истинное значение в C++ принимается любое ненулевое значение. Вспомните, что все печатные символы представляются значениями, не равными нулю, и только символ, завершающий строку, равен нулю. Следовательно, этот цикл работает до тех пор, пока индекс не укажет на нулевой признак конца строки, т.е. пока значение str[i] не станет нулевым. Поскольку нулевой символ отмечает конец строки, цикл останавливается в точности там, где нужно. При дальнейшей работе с этой книгой вы увидите множество примеров, в которых нулевой признак конца строки используется подобным образом.

Важно! Помимо функции toupper(), стандартная библиотека C++ содержит много других функций обработки символов. Например, функцию toupper() дополняет функция tolower(), которая возвращает строчный эквивалент своего символьного аргумента. Часто используются такие функции, как isalpha(), isdigit(), isspace() и ispunct(), которые принимают символьный аргумент и определяют, принадлежит ли он к соответствующей категории. Например, функция isalpha() возвращает значение ИСТИНА, если ее аргументом является буква (элемент алфавита).

 

Двумерные массивы

 

В C++ можно использовать многомерные массивы. Простейший многомерный массив – двумерный. Двумерный массив, по сути, представляет собой список одномерных массивов. Чтобы объявить двумерный массив целочисленных значений размером 10x20 с именем twod , достаточно записать следующее:

 

 

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

Чтобы получить доступ к элементу массива twod с координатами 3,5 , необходимо использовать запись twod[3][5] . В следующем примере в двумерный массив помещаются последовательные числа от 1 до 12 .

 

 

В этом примере элемент num[0][0] получит значение 1 , элемент num[0][1] – значение 2 , элемент num[0][2] – значение 3 и т.д. Значение элемента num[2][3] будет равно числу 12 . Схематически этот массив можно представить, как показано на рис. 5.1.

В двумерном массиве позиция любого элемента определяется двумя индексами. Если представить двумерный массив в виде таблицы данных, то один индекс означает строку, а второй – столбец. Из этого следует, что, если к доступ элементам массива предоставить в порядке, в котором они реально хранятся в памяти, то правый индекс будет изменяться быстрее, чем левый.

 

 

Необходимо помнить, что место хранения для всех элементов массива определяется во время компиляции. Кроме того, память, выделенная для хранения массива, используется в течение всего времени существования массива. Для определения количества байтов памяти, занимаемой двумерным массивом, используйте следующую формулу.

число байтов = число строк х число столбцов х размер типа в байтах

Следовательно, двумерный целочисленный массив размерностью 10x5 занимает в памяти 10x5x2 , т.е. 100 байт (если целочисленный тип имеет размер 2 байт).

 

Многомерные массивы

 

В C++, помимо двумерных, можно определять массивы трех и более измерений. Вот как объявляется многомерный массив.

 

 

Например, с помощью следующего объявления создается трехмерный целочисленный массив размером 4x10x3 .

 

 

Как упоминалось выше, память, выделенная для хранения всех элементов массива, используется в течение всего времени существования массива. Массивы с числом измерений, превышающим три, используются нечасто, хотя бы потому, что для их хранения требуется большой объем памяти. Например, хранение элементов четырехмерного символьного массива размером 10x6x9x4 займет 2 160 байт . А если каждую размерность увеличить в 10 раз, то занимаемая массивом память возрастет до 21 600 000 байт . Как видите, большие многомерные массивы способны "съесть" большой объем памяти, а программа, которая их использует, может очень быстро столкнуться с проблемой нехватки памяти.

 

Инициализация массивов

 

В C++ предусмотрена возможность инициализации массивов. Формат инициализации массивов подобен формату инициализации других переменных.

 

 

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

Например, в следующем примере 10 ‑элементный целочисленный массив инициализируется числами от 1 до 10 .

 

 

После выполнения этой инструкции элемент i[0] получит значение 1 , а элемент i[9] –значение 10 .

Для символьных массивов, предназначенных для хранения строк, предусмотрен сокращенный вариант инициализации, который имеет такую форму,

 

 

Например, следующий фрагмент кода инициализирует массив str фразой "привет" ,

 

 

Это равнозначно поэлементной инициализации.

 

 

Поскольку в C++ строки должны завершаться нулевым символом, убедитесь, что при объявлении массива его размер указан с учетом признака конца. Именно поэтому в предыдущем примере массив str объявлен как 7 ‑элементный, несмотря на то, что в слове "привет" только шесть букв. При использовании строкового литерала компилятор добавляет нулевой признак конца строки автоматически.

Многомерные массивы инициализируются по аналогии с одномерными. Например, в следующем фрагменте программы массив sqrs инициализируется числами от 1 до 10 и квадратами этих чисел.

 

 

Теперь рассмотрим, как элементы массива sqrs располагаются в памяти (рис. 5.2).

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

 

 

 

 

При использовании подгрупп инициализаторов недостающие члены подгруппы будут инициализированы нулевыми значениями автоматически.

В следующей программе массив sqrs используется для поиска квадрата числа, введенного пользователем. Программа сначала выполняет поиск заданного числа в массиве, а затем выводит соответствующее ему значение квадрата.

 

 

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

 

 

При выполнении этой программы получаем такие результаты.

 

 

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

 

"Безразмерная" инициализация массивов

 

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

 

 

Нетрудно предположить, что вручную неудобно подсчитывать символы в каждом сообщении, чтобы определить корректный размер массива. К счастью, в C++ предусмотрена возможность автоматического определения длины массивов путем использования их "безразмерного" формата. Если в инструкции инициализации массива не указан его размер, C++ автоматически создаст массив, размер которого будет достаточным для хранения всех значений инициализаторов. При таком подходе предыдущий вариант инициализации массивов для построения таблицы сообщений об ошибках можно переписать так.

 

 

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

"Безразмерная" инициализация массивов не ограничивается одномерными массивами. При инициализации многомерных массивов вам необходимо указать все данные, за исключением крайней слева размерности, чтобы С++‑компилятор мог должным образом индексировать массив. Используя "безразмерную" инициализацию массивов, можно создавать таблицы различной длины, позволяя компилятору автоматически выделять область памяти, достаточную для их хранения.

В следующем примере массив sqrs объявляется как "безразмерный".

 

 

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

 

Массивы строк

 

Существует специальная форма двумерного символьного массива, которая представляет собой массив строк. В использовании массивов строк нет ничего необычного. Например, в программировании баз данных для выяснения корректности вводимых пользователем команд входные данные сравниваются с содержимым массива строк, в котором записаны допустимые в данном приложении команды. Для создания массива строк используется двумерный символьный массив, в котором размер левого индекса определяет количество строк, а размер правого – максимальную длину каждой строки. Например, при выполнении следующей инструкции объявляется массив, предназначенный для хранения 30 строк длиной 80 символов,

 

 

Массив строкэто специальная форма двумерного массива символов.

Получить доступ к отдельной строке довольно просто: достаточно указать только левый индекс. Например, следующая инструкция вызывает функцию gets() для записи третьей строки массива str_array .

 

 

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

 

 

Обратите внимание на то, как в программе выполняется проверка на ввод пустой строки. Функция gets() возвращает строку нулевой длины, если единственной нажатой клавишей оказалась клавиша <Enter> . Это означает, что первым байтом в строке будет нулевой символ. Нулевое значение всегда интерпретируется как ложное, но взятое с отрицанием (! ) дает значение ИСТИНА, которое позволяет выполнить немедленный выход из цикла с помощью инструкции break .

 


Дата добавления: 2018-09-22; просмотров: 422; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!