Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на C / C++ / Нейбауэр А. Моя первая программа на С.doc
Скачиваний:
182
Добавлен:
02.05.2014
Размер:
3.75 Mб
Скачать

Будьте осторожны при использовании scanf()

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

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

Ввод в Си++

Компиляторы языка Си++ поддерживают функции gets(), getchar() и scanf(), о которых мы говорили в этой главе. Кроме того, Си++ имеет собственное многоцелевое средство ввода для всех типов данных. Стандартный поток ввода cin в сочетании с двумя символами «больше» (>>), которые называются оператором извлечения*, служит для считывания данных с клавиатуры. Программа

int count;

cin >> count;

вносит целочисленные данные с клавиатуры в значение переменной count. Стандартный поток ввода cin не требует указания адреса переменной для числовых и символьных данных, указывается только имя переменной.

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

При работе с несколькими аргументами необходимо отделять каждое имя переменной оператором извлечения:

Рис. 5.11. Оператор вставки и оператор извлечения

cin >> amount >> count >> age >> name;

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

_____________________________

* В оригинале extraction operator. (Прим.перев.)

Оператор извлечения >> изображен в виде стрелки, направленной в сторону переменной. Это означает, что данные поступают к ней в виде ввода. Когда вы применяете cin для ввода данных, пользуйтесь оператором, который как бы указывает направление к переменной.

Оператор вставки << изображен в виде стрелки, направленной от переменной. Это значит, что данные выводятся из переменной на экран. Со стандартным потоком вывода cout используйте, соответственно, тот оператор, который как бы указывает направление от переменной.

Неинициализированные переменные

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

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

Чтобы избежать неприятностей, многие программисты присваивают начальные значения всем переменным. Можно присвоить ноль в качестве начального значения числовой переменной и пробел символьной и строковой переменным:

int count = 0;

char initial = ' ';

float rate = 0.0;

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

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

Большинство интерпретаторов (например, языка BASIC) и многие компиляторы автоматически присваивают числовым переменным ноль в качестве начального значения.

В табл. 5.1 собраны все средства ввода данных, о которых говорилось в этой главе.

Таблица 5.1. Основные средства ввода данных в языке Си/Си++.