Читать интересную книгу Язык Си - руководство для начинающих - M. УЭИТ

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 38 39 40 41 42 43 44 45 46 ... 98

установить 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?

м

Гм ... слишком мало. Ваше число 68?

м

Гм ... слишком мало. Ваше число 71?

д

Я знала, что смогу сделать это!

     Что может быть неправильного в этой программе? Мы реализовали в ней защиту от ошибок, вызванных тем, что пользователи могут указывать неверные символы, поэтому здесь не должно быть никаких проблем. Единственное, что может повлиять на правильность работы программы: если вы вместо м укажете б, или наоборот. К сожалению, не существует способа заставить пользователя говорить правду и не делать ошибок. Тем не менее, если вы заинтересованы в этом, можете предпринять некоторые шаги. (Например, если захотите поразить свою шестилетнюю племянницу.) Во-первых, обратите внимание на то, что наш способ требует самое большее семи попыток для угадывания любого числа. (Каждая попытка уменьшает число возможностей наполовину. За семь попыток можно угадать любое число в диапазоне от 1 до 27- 1, или 127, что вполне достаточно для работы в диапазоне или 1 до 100.) Вы можете модифицировать программу так, чтобы она подсчитывала число попыток, и если окажется, что оно превышает 7, то тогда можно вывести на печать сообщение с выражением недовольства, а затем восстановить первоначальные значения переменных highest, lowest и счетчика. Дополнительные изменения, которые можно внести в программу, заключаются в такой модификации операторов if, в результате которой допускался бы ввод как прописных, так и строчных букв.

Резюме: оператор while

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

while(выражение) оператор

     Выполнение оператора циклически повторяется до тех пор, пока выражение не станет ложным, или равным нулю.

ПРИМЕРЫ

while(n++ < 100) printf(" %d %d n",n, 2*n + 1);

while(fargo < 1000)

{

 fargo = fargo + step;   step = 2 * step;

}

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

main( )

{

 int = 1;                      /* инициализация */

   while (count <= NUMBER)    /* проверка     */

    {

      printf(" Будь моим Валентином !n");   /*действие */

      count++;                  /* увеличение счетчика */   

    }

}

     Хотя цикл подобного типа прекрасно работает, это не лучший вариант его записи, поскольку операции, реализующие цикл, не собраны вместе. Рассмотрим этот вопрос более подробно. При организации цикла, когда его тело должно быть выполнено фиксированное число раз, осуществляются три операции: инициализация счетчика, сравнение его величины с некоторым граничным значением и увеличение значения счетчика при каждом прохождении тела цикла. Условное выражение, имеющееся в цикле while, берет на себя заботу о сравнении, а приращение значения счетчика осуществляется с помощью операции увеличения. Так же как это делалось раньше, можно объединить эти два действия в одно выражение, используя запись count++ <= NUMBER. Но инициализация счетчика осуществляется вне цикла, как, например, в нашем примере оператором count = 1;. При этом можно забыть о необходимости инициализации счетчика, а то, что может случиться, рано или поздно случается. Сейчас мы рассмотрим управляющий оператор, использование которого позволяет избежать этих проблем.

ЦИКЛ for 

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

for(count = 1; count <= NUMBER; count++)

    printf(" Будь моим Валентином! n ");

     В круглых скобках содержатся три выражения, разделенные символом "точка с запятой". Первое из них служит для инициализации счетчика. Она осуществляется только один раз - когда цикл for начинает выполняться. Второе выражение - для проверки условия; она производится перед каждым возможным выполнением тела цикла. Когда выражение становится ложным (или в общем случае равным нулю), цикл завершается. Третье выражение вычисляется в конце каждого выполнения тела цикла. Ранее мы использовали его для увеличения значения счетчика count, но, вообще говоря, его использование этим не ограничивается. За заголовком цикла for следует простой или составной оператор. Рис. 8.3 служит иллюстрацией структуры цикла for.

1 ... 38 39 40 41 42 43 44 45 46 ... 98
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Язык Си - руководство для начинающих - M. УЭИТ.

Оставить комментарий