Мы следовали модульному подходу, используя отдельные функции (модули) для проверки допустимости ввода и для управления отображением. Чем крупнее программа, тем важнее становится модульный подход.
Функция main() управляет потоком, делегируя задачи другим функциям. Функция get int() применяется в ней для получения значений, цикл while — для их обработки, функция badlimits() — для проверки допустимости значений и функция sum squares() — для выполнения действительных вычислений:

Поток ввода и числа
При написании кода для обработки некорректного ввода, такого как в листинге 8.7, вы должны иметь четкое представление о том, как происходит ввод в С. Рассмотрим следующую строку ввода:
is 28 12.4
Для наших глаз этот ввод выглядит подобным строке символов, за которой следует целое число, а за ним значение с плавающей запятой. Для программы на С он выглядит подобно потоку байтов. Первый байт — это символьный код для буквы i, второй байт — символьный код для буквы s, третий байт — символьный код для пробела, четвертый байт — символьный код для цифры 2 и т.д. Таким образом, если функции get int() встретится эта строка, начинающаяся нецифрового символа, то приведенный ниже код прочитает и отбросит всю строку целиком, включая числа, которые являются просто еще одной разновидностью символов в строке:
while ((ch = getchar()) != '\n')
putchar(ch); // отбросить неправильный ввод
Хотя входной поток состоит из символов, функция scanf() может преобразовать их в числовое значение, если вы сообщите ей об этом.
316 Глава 8
Например, рассмотрим следующий ввод:
42
Если вы используете функцию scanf() со спецификатором %с, она прочитает только символ 4 и сохранит его в переменной типа char. В случае указания спецификатора %s функция прочитает два символа, символ 4 и символ 2, и сохранит их в символьной строке. Если применить спецификатор %d, то scanf() прочитает те же два символа, но приступит к вычислению соответствующего им целочисленного значения, т.е. 4 х 10 + 2, или 42. Затем она сохранит целочисленное двоичное представление этого значения в переменной типа int. При указании спецификатора %f функция scanf() прочитает два символа, вычислит, что они соответствуют числовому значению 42.0, выразит это значение во внутреннем представлении с плавающей запятой и сохранит результат в переменной типа float.
Короче говоря, ввод состоит из символов, но scanf() может преобразовать этот ввод в целочисленное значение или значение с плавающей запятой. Использование спецификатора вроде %d или If ограничивает типы символов, являющихся приемлемым вводом, но функция getchar() и функция scanf(), в которой указан спецификатор %с, принимают любой символ.
Просмотр меню
Во многих компьютерных программах в качестве части пользовательского интерфейса применяется меню. Меню делают программы более удобными для пользователя, по ставят определенные задачи перед программистами. Давайте посмотрим, в чем они состоят. Меню предлагает пользователю варианты ответа. Вот гипотетический пример:
Введите букву, соответствующую выбранному варианту:
с. совет з. звонок
п. подсчет в. выход
В идеальном случае пользователь вводит одну из предложенных букв, и программа действует согласно выбору. Будучи программистом, вы хотите, чтобы этот процесс протекал как можно более гладко. Первая цель заключается в том, что программа должна работать корректно, если пользователь придерживается инструкций. Вторая цель состоит в том, что программа должна работать устойчиво в ситуациях, когда пользователь нарушает эти инструкции. Вполне ожидаемо, что второй цели достичь гораздо труднее, потому что трудно предугадать все возможные нарушения, с которыми может столкнуться программа.
В современных приложениях вместо ориентированного на командную строку подхода, рассмотренного в приведенных примерах, обычно используются графические интерфейсы (кнопки для щелчка, флажки для отметки, значки для касания), однако общий процесс остается во многом таким же — предоставление пользователю вариантов выбора, обнаружение и действие в соответствии с ответом пользователя, а также защита от возможного неправильного использования. Лежащая в основе этих различных интерфейсов программная структура во многом аналогична. Однако применение графического интерфейса может упростить управление вводом за счет ограничения доступных для выбора вариантов.
Читать дальше