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

Дополненный Опросник

В главе 7 мы предложили в качестве примера несколько программ, которые выводили на экран монитора вопросы и ответы. Поскольку вы тогда еще не познакомились c инструкцией if, то не имели возможности вести подсчет очков за правильные ответы. Подсчет очков, как демонстрирует программа из Листинга8.3, представляет собой, по существу, сравнение правильного ответа, заложенного в тексте программы, и ответа, введенного с клавиатуры.

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

ask("9+5= ", 14);

Листинг 8.3. Опросник с подсчетом очков.

/*score*/

int correct, wrong;

main()

{

char question[15];

int answer;

correct = 0;

wrong = 0;

ask("4 + 5 = ", 9);

ask("6 + 2 = ", 8);

ask("5 + 5 = ", 10);

ask("4 + 7 = ", 11);

printf ("Количество верных ответов: %d.\n", correct);

printf ("Количество неверных ответов: %d.\n", wrong);

}

ask(quest, ans)

char quest[15];

int ans;

{

int guess;

printf("%s", quest);

scanf("%d", &guess);

if (guess == ans)

++correct;

else

++wrong;

return(0);

}

Логические операторы

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

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

Листинг 8.4. Работа программы основывается на указаниях пользователя.

/*iftax.c*/

main()

{

int taxable;

float cost, tax;

tax = 0.0;

printf("Введите цену товара: ");

scanf("%f", &cost);

printf("Введите Y, если товар облагается налогом, N, если не облагается: ");

taxable = getchar();

if (taxable == 'Y')

tax = cost * 0.06;

printf("\nСтоимость товара с учетом налога составляет %f", cost + tax);

}

Если на ваш взгляд программа написана вполне корректно, посмотрите ее текст еще раз более внимательно — там есть серьезное упущение. Программа написана так, что пользователь должен в ответ на запрос ввести прописную букву Y, если товар облагается налогом. Если пользователь вводит строчную букву y, программа будет считать, что налог в данном случае не взимается, ведь в инструкции if в качестве правильного условия рассматривается только прописная буква.

Замечания по использованию функции getchar()

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

Кроме того, использование функции getchar() после ввода с помощью scanf() может создать дополнительную проблему. В главе 5 мы говорили, что данные, формат которых не соответствует ожидаемому (указанному в строке формата), функция scanf() игнорирует, и они остаются в буфере. Функция getchar() может прочитать один из этих символов еще до того, как будет введен нужный символ. Можно избежать подобной опасности, если вместо scanf() использовать функцию gets() либо, если ваш компилятор позволяет это, применить функции ввода символов без буферизации, такие как getch() или getche().

Другим возможным решением является очистка буфера перед каждой функцией getchar(). Добавьте в начало программы директиву #include , а затем вставьте функцию fflush(stdin) перед вызовом getchar(). Функция fflush() удаляет все символы, которые могли остаться в буфере стандартного устройства ввода.

В подобной ситуации правильнее было бы проверять оба возможных варианта ввода, то есть и строчную и прописную буквы Y. Можно сделать это с помощью двух инструкций if. А можно использовать логический оператор ИЛИ, который выглядит как две вертикальные черты:

if (taxable == 'Y' || taxable == 'y')

В данной инструкции сказано: «Если переменная taxable имеет значение Y ИЛИ y, то...» Таким образом, мы добьемся того, что товар будет рассматриваться как облагаемый налогом, если выполняется одно из этих двух условий. Если не выполняется ни одно из них, то есть пользователь ввел любой другой символ, товар будет считаться не облагаемым налогом. Условие должно быть целиком помещено в круглые скобки, причем имя переменной taxable следует повторить дважды. Запись условия как (taxable == 'Y' || 'y') приведет к ошибке компиляции.

Есть три логических оператора: ИЛИ (||), И (&&) и отрицания (!). Оператор ИЛИ означает, что для выполнения инструкции if достаточно истинности одного из двух (или обоих вместе) заданных условий. Оператор И указывает на то, что должны быть истинными оба условия одновременно. Оператор отрицания означает, что инструкция if выполняется, если некое условие оказалось ложным.

Операторы И и ИЛИ можно использовать не только для проверки равенства переменной одному из двух значений (как мы уже делали), но и для тестирования значений различных переменных. Например, вы пишете программу, в которую вводится размер годового дохода пользователя и количество иждивенцев (Листинг8.5).

Листинг 8.5. Проверка значений двух переменных.

/*twovars.c*/

main()

{

int depents;

float income;

puts("Укажите сумму Вашего годового дохода");

scanf("%f", &income);

puts("Пожалуйста, укажите количество иждивенцев");

scanf("%d", &depents);

if (income < 20000 && depents > 2)

puts("Вы освобождены от уплаты подоходного налога");

}

В условии if здесь проверяются значения двух переменных: income и depents. Для того чтобы сообщение, записанное в инструкции if, оказалось выведенным на экран, значение переменной income должно быть меньше 20 тысяч долларов, И одновременно значение переменной depents должно быть больше двух. Если хотя бы одно из перечисленных условий не выполняется, например, количество иждивенцев равно одному или доход составляет 20001 доллар, функция puts() не будет выводить на экран сообщение об освобождении от уплаты налога.

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

if (taxable == 'Y' && taxable == "y")

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

Для примера предположим, что налогом на предметы роскоши облагаются товары, цена которых находится в пределах от 40 тысяч до 60 тысяч долларов. Условие проверяется следующим образом:

if (cost >= 40000.00 && cost <= 60000.00)

Для того чтобы выполнялась инструкция if, должны быть истинными оба условия одновременно, так как мы использовали оператор И. При этом цена товара должна быть в одно и то же время больше или равна 40000 и меньше или равна 60000 долларов, то есть находится в пределах определенных допустимых значений (рис.8.3).

Если в данном случае использовать оператор ИЛИ, то это приведет к ошибочному выполнению инструкции, так как любое значение переменной cost будет рассматриваться как удовлетворяющее условию. Напротив, если мы хотим

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

определить, находится ли значение вне каких-то установленных границ значений, мы должны использовать именно оператор ИЛИ и поменять местами операторы «больше или равно» и «меньше или равно». При такой записи условие if будет проверять, выходит ли значение числа за указанные рамки, определяя, меньше это число или больше установленных ограничивающих значений:

if (income <= 20000.00 || income >= 60000.00)

puts("Вы не относитесь к среднему классу");

Оператор отрицания называют унарным оператором, так как он работает только с одним объектом, а именно, с переменной или константой. Условие считается не выполненным (ложным) в том случае, когда значение выражения, стоящего в круглых скобках после if, равно0. При любом другом значении выражения, будь оно положительным или отрицательным, полагается, что условие выполнено. Например, следующие инструкции выводят на экран монитора сообщение: «Ошибка в расчете», так как переменная count имеет значение, равное0:

int count;

count = 0;

if (! count) puts("Ошибка в расчете");

Такая запись условия в точности соответствует строке

if (count == 0)

Аналогичным образом, следующая инструкция выводит на экран сообщение: «Правильный результат», так как переменная count имеет значение, отличное от нуля:

int count;

count = 1;

if (count) puts("Правильный результат");

Запись if (count) аналогична записи if (count != 0), которая определяет, отличается ли значение переменной от нуля. В последующих главах вы узнаете, как используются унарные операторы.