Язык Си - руководство для начинающих
Шрифт:
И этот фрагмент программы работает ненамного лучше. Значение переменной index в нем изменяется, но в "неправильном" направлении! Единственным утешением здесь служит тот факт, что выполнение данного куска программы в конце концов завершится. Это произойдет, когда величина переменной index станет меньше наименьшего отрицательного числа, допустимого в системе.
Цикл while является "условным" циклом, использующим предусловие (т.е. условие на входе). Он называется условным, потому что выполнение оператора зависит от истинности условия, описываемого с помощью выражения. Действительно ли значение переменной index меньше 5? Является ли последний введенный символ признаком EOF? Подобное выражение задает
index = 10;
while(index++ < 5)
printf(" Желаю хорошо провести день.\n");
Измените первую строку на
index = 3;
и вы получите работающую программу.
АЛГОРИТМЫ И ПСЕВДОКОД
А теперь вернемся к нашей "тупоумной" программе, угадывающей число. Недостаток этой программы кроется не в программировании самом по себе, а в "алгоритме", т.е. методе, используемом для отгадывания числа. Этот метод можно описать следующим образом: попросите пользователя задумать число компьютер начинает угадывание с 1 до тех пор пока догадка неверна, предлагаемое значение увеличивается на 1.
Эта запись, между прочим, служит примером "псевдокода" представляющего собой способ выражения смысла программ на разговорном языке и являющегося некоторым аналогом языка машины. Псевдокод очень эффективен при разработке логики программы. После того как логика покажется вам правильной, вы можете обратить основное внимание на детали перевода псевдокода на реальный язык программирования. Преимущество использования псевдокода состоит в том, что он позволяет сконцентрироваться на логике и структуре программы, не заботясь пока о способе перевода этих идей на язык машины. Если мы хотим улучшить программу, нам в первую очередь необходимо улучшить алгоритм. Один из методов заключается в том, чтобы выбрать число где-нибудь посередине между 1 и 100 (50 нам вполне подходит) и попросить пользователя ответить больше ли это число задуманного, меньше его или равно ему. Если он сообщает, что данное число слишком велико, то тем самым из рассмотрения немедленно исключаются все числа между 50 и 100. Следующей догадкой программы является число, выбранное где-то посередине между 1 и 49. И снова ответ на вопрос, велико или мало это число, позволит исключить из рассмотрения половину оставшихся возможных чисел; программа продолжает указанный процесс, быстро сужая поле поиска до тех пор, пока задуманное число не будет угадано. Давайте запишем эти логические рассуждения на псевдокоде. Пусть highest– максимально возможная величина отгадываемого числа, a lowest– его минимально возможное значение. Вначале этими величинами будут соответственно 100 и 1, поэтому алгоритм запишется следующим образом:
установить highest равным 100
установить lowest равным 1
попросить пользователя задумать число
предложенное значение (guess) равно (highest + lowest)/2
пока догадка неверна, делать следующее:
{если предложенное значение велико, установить highest равным этому предложенному значению минус 1
если предложенное значение мало, установить lowest равным этому предложенному значению плюс 1
новое предложенное значение равно (highest + lowest)/2 }
Обратите внимание на логику алгоритма: если предложенное значение, равное 50, велико, то максимально возможная величина задуманного числа будет равна 49. Если же значение 50 мало, то минимально возможная величина числа будет равна 51.
Сейчас мы переведем текст, указанный выше, на язык Си. Полученная программа представлена на рис. 8.2.
/* угадывание числа2 */
/* более эффективный способ угадывания*/
#include
#define HIGH 100
#define LOW 1
main
{
int guess = (HIGH + LOW)/2;
int highest = HIGH;
int lowest = LOW;
char response;
printf(" Задумайте число от %d до %d. Я попробую", LOW, HIGH);
printf(" угадать eгo.\n Отвечайте д, если моя догадка правильна,");
printf(" б, если \n больше, и м, если");
printf(" меньше.\n");
printf(" Итак ... ваше число %d?\n" , guess);
while((response = getchar) != 'д')
{
if( response != '\n')
{
if (response == 'б')
{
/* уменьшение верхнего предела,
eсли предложенное значение слишком велико */
highest = guess - 1;
guess = (highest + lowest)/2;
printf(" Гм ... слишком велико. Ваше число %d?\n", guess);
}
else if(response == 'м')
{
/* увеличение нижнего предела,если
предложенное значение слишком мало*/
lowest = guess + 1;
guess = (highest + lowest)/2;
printf(" Гм ... слишком мало. Ваше число %d?\n" , guess);
}
else
{
/* подводите пользователя к правильному ответу */
printf(" Я не понимаю; введите, пожалуйста, д,б");
printf ("или м.\n");
}
}
printf("Я знала, что смогу сделать это!\n");
}
РИС. 8.2. Программа, угадывающая число.
Наличие в программе завершающей части else предоставляет пользователю дополнительную возможность правильно ответить на стандартный "отклик" программы. Заметим также, что мы использовали символические константы, чтобы сделать процесс изменения диапазона чисел достаточно простым. Работает ли данная программа? Ниже приводятся результаты этого прогона. Задуманное число - 71.
Задумайте число от 1 до 100. Я попробую угадать eгo
Отвечайте д, если моя догадка правильна б, если
больше, и м, если меньше.
Итак ..., ваше число 50?
Я не понимаю: введите, пожалуйста, д,б или м.
м
Гм ... слишком мало. Ваше число 75?
б
Гм ... слишком велико. Ваше число 62?