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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 45 46 47 48 49 50 51 52 53 ... 98

Это подводит нас к следующему методу, при котором в программе осуществляется подсчет количества вводимых чисел. После всего сказанного выше очевидно, что у компьютеров имеются для этого вес возможности. Основная проблема здесь состоит в том, как сообщить компьютеру о завершении ввода чисел. Один из методов - дать пользователю возможность вводить специальный признак, указывающий на конец ввода. Признак должен принадлежать к данным того же типа, что и остальные вводимые данные, так как он должен быть прочитан тем же оператором программы. Но при этом он должен отличаться от обычных данных. К примеру, если бы мы вводили результаты игры, чтобы узнать, кто набрал от 0 до 100 очков, мы не могли бы выбрать число 74 в качестве такого признака, потому что оно может соответствовать некоторому возможному результату. С другой стороны, например, число 999 или - 3 вполне могло бы подойти в качестве такого признака, поскольку оно не соответствует требуемому результату.

 Ниже приводится программа, являющаяся реализацией этого метода:

#define STOP 999 /* признак завершения ввода */

#define NUM 50

main( )

{

int i, count, temp, score [NUM];

printf(" Начните ввод результатов. Введите 999 для указания n");

printf(" конца ввода. Максимальное число результатов, которое выn");

printf(" можете ввести.- это %d.n", NUM);

count = 0;

scanf(" %d", &temp); /* вводвеличины*/

while(temp != STOP && count <= NUM) /* проверка наличия признака STOP */

{ /* и проверка, не произошло ли превышения размера массива */

score[count++] = temp;

/* запись величины в память и коррекция счетчика */

if(count < NUM + 1)

        scanf("%d", &temp); /* ввод очередного результата */

else

        printf("Я не могу принять больше данных.n");

}

printf("Bы ввели %d результатов, а именно:n", count);

for(i = 0; i < count; i++)

        printf("%5dn", scorc[i]);

}

     Мы вводим данные во временную переменную temp и присваиваем ее значение соответствующему элементу массива только в том случае, если оно не является признаком конца ввода. Совершенно не обязательно реализовывать все именно так; мы просто считаем, что указанный способ делает процесс проверки несколько более наглядным.

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

     Заметьте также, что мы воспользовались постфиксной формой операции увеличения. Поэтому, когда значение count равно 0, элементу массива score[0] присваивается величина переменной temp, а затем count возрастает на 1. После каждой итерации цикла while величина счетчика count становится на единицу больше последнего использованного индекса массива. Это как раз то, что нам нужно, поскольку score[0] - первый элемент, score[20] - 2-й элемент и т. д. Когда работа цикла в программе завершается, значение count оказывается равным полному чиcлу прочитанных элементов данных. Затем величина count используется в качестве верхней границы числа итераций для последующих циклов.

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

     Мы столкнулись с аналогичной проблемой, когда искали подходящий символ для признака End-of-File. Тогда было принято решение использовать для ввода символов специальную функцию(getchar( )), которая при обращении к ней фактически возвращала величину типа int. Это позволяло функции читать "символ" EOF, который на самом деле не был обычным символом. В рассматриваемом нами примере полезной оказалась бы функция, которая осуществляла бы ввод целых чисел, могла бы, кроме того, читать данные не только целого типа, но и использовать их в качестве признака конца ввода.

     Мы можем одновременно и обрадовать и огорчить вас: такое решение оказывается возможным, но вы должны узнать несколько больше о работе функций; поэтому обсуждение данной идеи откладывается до гл. 10.

РЕЗЮМЕ

Основной темой данной главы было обсуждение возможностей управления ходом выполнения программы. Язык Си предоставляет много средств для структурирования программ. С помощью операторов while и for реализуются циклы с предусловием. Второй оператор особенно подходит для циклов, включающих в себя инициализацию и коррекцию переменной. Использование операции "запятая" в цикле for позволяет инициализировать и корректировать более одной переменной. Для тех редких случаев, когда требуется использовать цикл с постусловием, язык Си предоставляет оператор do while. Операторы break, continue и goto обеспечивают дополнительные возможности управления ходом выполнения программы.  

ЧТО ВЫ ДОЛЖНЫ БЫЛИ УЗНАТЬ В ЭТОЙ ГЛАВЕ

Три типа циклов в языке Си: while, for и do while.

Различие между циклами с предусловием и с постусловием.

Почему циклы с предусловием используются гораздо чаще, чем циклы с постусловием.

Дополнительные операции присваивания: +=    -=    *=    /=    %=.

Как пользоваться операцией "запятая".

Когда использовать операторы break и continue: по возможности редко.

Когда использовать оператор goto: когда вы хотите иметь неудобные, трудные для понимания программы.

Как использовать оператор while для защиты программы от ошибок при вводе данных.

ВОПРОСЫ И ОТВЕТЫ

Вопросы

1. Определите значение переменной quack после выполнения каждого оператора из приведенной ниже их последовательности.

     int quack = 2;

     quack + = 5;

     quack * = 10;

     quack - = 6;

     quack / = 8;

     quack % = 3;

2. Что будет получено на выходе в результате работы следующего цикла?

     for(value = 36; value > 0; value /= 2) printf("%3d", value);

3. Как можно модифицировать операторы if в программе угадывание числа2 чтобы был возможен ввод как прописных, так и строчных букв?

4. Мы подозреваем, что следующая программа не совсем правильная. Какие ошибки вы сможете в ней обнаружить?

main( )        /* строка 1 */ 

{        /* строка 2 */

int i, j, lisl[10];        /* строка 3 */

for (i = 1, i < = 10, i++ )        /* строка 5 */

{        /* строка 6 */

list[i] = 2*i + 3;        /* строка 7 */

for(j = 1, j >= i, j++ )        /* строка 8 */

printf(" %d n", lisl[j]);        /* строка 9 */

}        /* строка 10 */

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

$$$$$$$$ $$$$$$$$ $$$$$$$$ $$$$$$$$  

6. Напишите программу, которая создает массив из 26 элементов и помещает в него 26 строчных букв.

Ответы

1.     2, 7, 70, 64, 8, 2

2.     36 18 9 4 2 1.

Вспомните, как выполняется деление целых чисел. Результатом деления 1 на 2 будет 0, поэтому работа цикла завершится после того, как переменная value станет равной 1.

3. if(response == 'б' || response == 'Б').

4.     строка 3: должно быть list[10].

     строка 5: вместо запятых должны стоять символы "точка с запятой".

     строка 5: переменная i должна изменяться в диапазоне от 0 до 9, а не от 1 до 10.

     строка 8: вместо запятых должны стоять символы "точка с запятой".

     строка 8: знак >= должен быть заменен на <=. В противном случае при значении i, равном 1, цикл никогда не завершится.

     строка 10: между строками 9 и 10 должна находиться еще одна закрывающая фигурная скобка. Одна скобка закрывает составной оператор, а другая тело программы.

5.

main( )6.

{ int i, j;

for(i = 1; i <= 4; i++)

1 ... 45 46 47 48 49 50 51 52 53 ... 98
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Язык Си - руководство для начинающих - M. УЭИТ.

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