Программирование >>  Динамические структуры данных 

[ 1 ] 2 3 4 ... 38


Динамические структуры данных

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

Программа на С++ состоит из функций. Функция - это именованная последовательность операторов; Функция состоит из заголовка и тела. Строка, помеченная комментарием 1, представляет собой заголовок главной (а в данном случае и единственной) функции программы. Она должна иметь имя main, указывающее, что именно с нее требуется начинать выполнение. Заголовок любой функции пишется по определенным правилам. За именем функции в скобках обычно следует список передаваемых ей параметров. В данном случае он пуст, но скобки необходимы для того, чтобы компилятор мог распознать, что это именно функция, а не другая конструкция языка. Перед именем записан тип значения (int - целое), возвращаемого функцией в точку ее вызова (в данном случае - во внешнюю среду). По стандарту главная функция должна возвращать целочисленное значение. Забегая вперед, скажем, что этим в нашей программе занимается оператор 7. Впрочем, многие компиляторы реагируют спокойно и в случае, если функция ничего не возвращает.

После круглых скобок в фигурных скобках записывается тело функции, то есть те операторы, которые требуется выполнить. Для удобства восприятия принято располагать тело с отступом в 3-4 позиции от заголовка. Обратите внимание, что закрывающая скобка находится в той же колонке, что и первый символ заголовка функции. Это требование хорошего стиля, а не синтаксиса.

Препроцессором называется предварительная фаза компиляции, то есть перевода программы с С++ на машинный язык.

Для хранения исходных данных и результатов надо выделить достаточно места в оперативной памяти. Для этого служит оператор 2. В нашей программе требуется хранить два значения: температуру по Цельсию и температуру по Фаренгейту, поэтому в операторе определяются две переменные. Одна, для хранения температуры по Фаренгейту, названа fahr, другая (по Цельсию) - eels.

ВНИМАНИЕ -

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

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

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

ПРИМЕЧАНИЕ -

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

Для того, чтобы пользователь программы (пока что это вы сами) знал, в какой момент требуется ввести с клавиатуры данные, применяется так называемое приглашение к вводу (оператор 3). На экран выводится указанная в операторе строка символов, и курсор переводится на следующую строку. Строка символов, более строго называемая символьным литералом, - это последовательность любых пред-ставимых в компьютере символов, заключенная в кавычки. Стандартный объект, с помощью которого выполняется вывод на экран, называется eout. Ему с помощью операции передается то, что мы хотим вывести. Для вывода нескольких элементов используется цепочка таких операций. Для перехода на следующую строку записывается волшебное слово endl. Это - так называ-

Впрочем, существуют яэы1си, в которых отсутствует предварительное описание типа, при этом он определяется по контексту. Тем, кто испытывает непреодолимое отвращение к описаниям типа, можно порекомендовать вместо С++, например, язык Perl.



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

СОВЕТ---.-

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

В операторе 4 выполняется ввод с клавиатуры одного числа в переменную fahr. Для этого используется стандартный объект cin и операция извлечения (чтения) . Как видите, семантика ввода очень проста и интуитивно понятна: значение со стандартного ввода передается в переменную, указанную справа. Если требуется ввести несколько величин, используется цепочка операций . В процессе ввода число преобразуется из последовательности символов, набранных на клавиатуре, во внутреннее представление вещественного числа и помещается в ячейку памяти, зарезервированную для переменной fahr.

В операторе 5 вычисляется выражение, записанное справа от операщи присваивания (обозначаемой знаком -), и результат присваивается переменной eel s, то есть заносится в отведенную этой переменной память. Выражение - это правило для вычисления некоторого значения, можно назвать его формулой. Порядок вычислений определяется приоритетом операций (Учебник, с. 384). Уровней приоритетов в языке С++ огорчительно много, поэтому в случае сомнений надо не лениться обращаться к справочной информации, а вот запоминать подобные вещи в деталях мы бы не рекомендовали - есть и более полезные применения головному мозгу. Основные правила, тем не менее, просты и соответствуют принятым в математике: вычитание имеет более низкий приоритет, чем умножение, поэтому для того, чтобы оно было выполнено раньше, соответствующая часть выражения заключается в скобки. Деление и умножение имеют одинаковый приоритет и выполняются слева направо, то есть сначала целая константа 5 будет поделена на целую константу 9, а затем результат этой операции умножен на результат вычитания числа 32 из переменной fahr. Мы вернемся к обсуждению этого оператора позже, а пока рассмотрим два оставшихся.

Для вывода результата в операторе 6 применяется уже знакомый нам объект cout. Выводится цепочка, состоящая из четырех элементов. Это строка По Фаренгейту: , значение переменной fahr, строкав градусах Цельсия: и значение переменной eels. Обратите внимание, что при выводе строк все символы, находящиеся внутри кавычек, включая и пробелы, выводятся без изменений. При выводе значений переменных выполняется преобразование из внутреннего представления числа в строку символов, представляющую это число. Под значение отводится ровно столько позиций, сколько необходимо для вывода всех его значащих цифр. Это значит, что если вывести две переменные подряд, их значения склеятся , например:

eout fahr eels: плохо

cout fahr eels: чуть лучше

СОВЕТ --

Рекомендуется всегда предварять выводимые значения текстовыми пояснениями.

В одиночные кавычки в языке С++ заключается отдельный символ. В данном примере это пробел. Наконец, последний оператор (оператор 7) этой программы предназначен для возврата из нее и передачи значения во внешнюю среду. В главной функции разрешается его опускать, но в этом случае компилятор может выдать предупреждение (warning) и сформирует возвращаемое значение по умолчанию, равное нулю. Предупреждение можно проигнорировать, но, на наш взгляд, приятнее видеть в результате компиляции сообщение О errors, О warnings* (О ошибок, О предупреждений) или Success (успешное завершение) - при большом количестве запусков программы это экономит время, не отвлекая внимания. Наберите текст программы и скомпилируйте ее. Если вы видите сообщения об ошибках, сличите текст на экране с текстом в книге (последний - лучше).

ВНИМАНИЕ-----

При работе в интегрированной среде Borland С++ 3.1 (или любой другой оболочке, рассчитанной на работу в среде MS DOS) у вас не будет проблем с компиляцией и выполнением приводимых примеров. Напротив, работа в среде Microsoft Visual С++ 6.0 в режиме консольных приложений сопряжена с неудобствами, вызванными различными стандартами кодировки символов кириллицы в операционных системах MS DOS и Windows. Ниже мы рассмотрим этот вопрос подробнее.

Особенности работы в интегрированной среде Visual С++ 6.0

Мы предполагаем, что вы уже посмотрели в Приложении 1, как создаются приложения консольного типа, набрали текст приведенной выше программы, откомпилировали ее и запустили на выполнение. Вам приготовлен неприятный сюрприз: вместо приглашения Введите температуру по Фаренгейту вы увидите набор каких-то странных символов. Этому, конечно, должно быть какое-то объяснение. Начнем издалека. В старой доброй операционной системе MS DOS для кодировки символов используется стандарт ASCH, являющийся международным только в первой половине кодов (от О до 127), вторая половина кодов (от 128 до 255) является национальной и различна для разных стран.

Например, в России для второй половины таблицы ASCH используется так называемая альтернативная кодировка ГОСТа . В Windows же используется стандарт ANSI, в первой половине совпадающий с ASCH, а во второй половине отличающийся от его российского варианта. Разработчики интегрированной среды Visual С++ решили, что режим консольных приложений должен как бы имитировать работу в среде MS DOS, поэтому ввод-вывод выполняется в этом режиме в кодировке ASCII. В то же время в текстовом редакторе Visual С++, как и во всех Windows-



приложениях, используется кодировка ANSI. Теперь происхождение этих странных символов должно стать вам понятным.

Мы выяснили, кто виноват в рассматриваемой проблеме, осталось ответить на кардинальный вопрос - что делать? . Выходов, как всегда, два. Первый - перейти полностью на английский язык (что может оказаться плюсом в вашем резюме при поступлении на работу на совместное предприятие). Второй - использовать функцию CharToOemO для преобразования символов из кодировки ANSI в кодировку ASCII и функцию OeniToChar() для обратного преобразования. Очевидно, что первая из названных функций нужна для вывода русскоязычного текста на экран, а вторая - для ввода такого текста с клавиатуры, если в дальнейшем потребуется запись этого текста в документы (файлы) с кодировкой ANSI. Чтобы использовать обе эти функции, вы должны подключить к вашей программе заголовочный файл <windows .h>, который не предусмотрен стандартом языка С++.

Покажем, как будет выглядеть наша первая программа при ее реализации в среде Visual С++ 6.0 (приводится одно из возможных решений):

#include <iestream.h> linclude <windows.h>

char* Rus(const char* text):

int main(){ float fahr. eels:

cout endl Rus( Введите температуру по Фаренгейту ) endl: ein fahr:

eels 5 / 9 * (fahr - 32):

eout Rus( По Фаренгейту: ) fahr:

eout Rus( . в градусах Цельсия: ) eels endl:

return 0:

/

char bufRus[256]: char* Rus(const char* text){

CharToOem(text. bufRus):

return bufRus:

/

Непосредственное использование функции CharToOem() не всегда удобно. Дело в том, что эта функция возвращает значение типа BOOL а результат преобразования записывает по адресу своего второго аргумента. Поэтому вызов этой функции нельзя подставить на место строковой константы ни при использовании объектов вывода cout, ни при использовании библиотечных функций ввода-вывода.

Для решения проблемы мы написали свою небольшую функцию RusO, которая, обращаясь к функции CharToOem(), возвращает в качестве адреса преобразованной строки указатель на char (строки 9-12). В качестве временного хранилища преобразуемой строки функция использует глобальный массив bufRus длиной 256 символов (предполагается, что в качестве аргумента будут подставляться строки, не превышающие эту длину), описанный в операторе 8. Использовать функцию очень просто: любая строковая константа заменяется выражением Rus (строковая, константа). Кроме того, мы добавили в нашу программу так называемый прототип функции Rus (оператор 0). Он требуется компилятору для проверки правильности ее использования.

ПРИМЕЧАНИЕ -

Строго говоря, для использования такой функции в операциях вывода с объектом cout было бы правильнее потребовать, чтобы функция Rus () возвращала значение типа ссылки на класс ostreatn, но для этого нужно владеть основами работы с классами, поэтому к этому вопросу мы вернемся во второй части практикума. То, что функция RusO возвращает значение типа char*, приводит к следующему ограничению: ее нельзя использовать более одного раза в цепочке операций для одного объекта cout.

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

Отладка программы

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

Как вы можете видеть, результат выполнения программы со стабильностью, достойной лучшего применения, оказывается равным нулю! Это происходит из-за способа вычисления выражения. Давайте вновь обратимся к оператору 4. Константы 5 и 9 имеют целый тип, поэтому результат их деления также целочисленный. Округления при этом не происходит, дробная часть всегда отбрасывается. Естественно, что результат дальнейших вычислений не может быть ничем, кроме нуля. Исправить эту ошибку просто - достаточно записать хотя бы одну из констант в виде вещественного числа, например:

eels = 5. / 9 * (fahr - 32): 5

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

Эта функция пригодится нам на семинаре 6.

Это один из стандартных типов системы Windows, совпадающий по значению с типом bool языка С++.

Вопросам разработки функций посвящен семинар 7, а пока мы предлагаем вам просто принять наше решение на веру.

2 О глобальных переменных мы расскажем чуть позже, в разделе Описание переменных .



[ 1 ] 2 3 4 ... 38

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика