Чтение онлайн

ЖАНРЫ

Язык Си - руководство для начинающих

Д. МАРТИН

Шрифт:

printf(" У вас выпало %d, для %d %.0f-сторонних костей.\n", roll, dice, sides);

printf(" Сколько сторон? Введите 0 для завершения.\n");

scanf(" %f", &sides);

} printf(" Удачи вам!\n");

}

Теперь давайте используем эту программу:

Введите значение зерна

1

Введите число сторон кости, 0 для завершения.

6

Сколько

костей?

2

У вас выпало 4 для 2 6-сторонних костей.

Сколько сторон ? Введите 0 для завершения.

6

Сколько костей ?

2

У вас выпало 7 для 2 6-сторонних костей.

Сколько сторон? Введите 0 для завершения.

0

Удачи Вам!

Спасибо.

Вы можете использовать функцию rollemпо-разному. Пусть число сторон (sides) равно двум, тогда бросание) монеты даст следующий результат: "орел" выпал 2 раза, a "peшка" - один (или наоборот, смотря, что вы предпочитаете). Можно легко модифицировать программу, чтобы показать как отдельные результаты, так и итог. Или вы можете построить имитатор игры "крапс". Если вам нужно большое число бросаний, вы можете легко модифицировать свою программу и получить результат, подобный следующему:

Введите значение зерна.

10

Введите количество ходов; введите 0 для завершения.

18

Сколько сторон и сколько костей? 6 3

Здесь 18 ходов для 3 6-сторонних костей.

7 5 9 7 12 10 7 12 10 14

9 8 13 9 10 7 16 10

Сколько ходов? Введите 0 для завершения. 0

Использование функции rand[но не rоllem] изменило бы вашу программу угадывания чисел: компьютер стал бы выбирать, а вы угадывать, вместо того чтобы сделать наоборот.

Разработаем еще некоторые функции. Сначала мы хотим создать функцию, которая читает целые числа.

ФУНКЦИЯ ПОЛУЧЕНИЯ ЦЕЛЫХ ЧИСЕЛ: getint

План

К счастью, мы уже выработали стратегию. Во-первых, заметим, что любую вводимую информацию можно читать как строку символов. Целое число 324, например, можно прочитать как строку из трех символов: символ '3', символ '2' и символ '4'. Это подсказывает нам следующий план:

1. Прочитать вводимую информацию как символьную строку.

2. Проверить, состоит ли строка только из символов цифр и стоит ли перед ними знак плюс или минус.

3. Если все это имеет место, превратить символьную строку в правильное числовое значение.

4. Если нет, выдать предупреждение.

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

наша функция.

В частности, до того как мы займемся содержанием нашей функции getint, нужно точно решить, как она должна взаимодействовать со своим окружением: с какой информацией? Какую информацию она должна получать от вызывающей программы? Какую информацию должна возвращать? В каком виде должна быть эта информация? Снова мы рассматриваем функцию как черный ящик. Мы хотим знать, что входит в функцию и что выходит из нее и, наконец, что находится внутри ее. Этот подход помогает обеспечивать более однородное взаимодействие между различными частями программы. Иначе вы можете оказаться в положении человека, пытающегося установить трансмиссию автомашины "Волво" в автомобиль "Тойота". Сама функция правильная, но интерфейс является проблемой.

Поток информации для getint

Какой выход должна иметь наша функция? Во-первых, несомненно, что она должна была бы выдавать значение прочитанного числа. Конечно, функция scanf уже делает так. Во-вторых, и это очень существенно, мы собираемся создать такую функцию, которая будет выдавать сообщения о состоянии, т. е. найдено или нет целое число. Чтобы функция была действительно полезной, она должна также сообщать о нахождении ею символа EOF. Тогда мы могли бы использовать функцию getint в цикле while, который читает целые числа до тех пор, пока не обнаружит символ EOF. Короче говоря, нам нужно, чтобы getint возвращала два значения: целое числе и состояние.

Так как мы хотим иметь два значения, то с одной функцией return с этой задачей нам не справиться. Нам следует иметь два указателя. Однако полное решение задачи мы получим, если используем указатели для выполнения основной работы функции и функцию return для выдачи некоторого кода состояния. Именно это и делает функция scanf. Она возвращает количество символов, которые нашла, и символ EOF, если встречает его. Ранее мы не пользовались такой возможностью, но могли бы, если бы применяли вызов вида

status = scanf(" % d", &number);

Теперь будем это делать. Тогда наш вызов функции выглядел бы следующим образом:

status = getint(&number);

Правая часть равенства использует адрес переменной number, чтобы получить ее значение, a returnприменяется для получения значения переменной status.

РИС. 10.2. Создание функции getint

 Мы должны выбрать коды для выдачи сообщения о состоянии. Так как предполагается, что неописанные функции имеют тип int, наши коды должны состоять из целых чисел. Используем следующие коды для сообщения о состоянии:

– 1 означает, что найден символ EOF.

1 означает, что найдена строка, содержащая не цифры.

0 означает, что найдена строка, содержащая только цифры.

Нашу функцию getint можно представить себе (рис. 10.2) как имеющую один вход и два выхода. На ее вход поступает адрес целой переменной, значение которой считывается. На первом выходе имеем значение считанного целого, полученного через указатель. (Таким образом, аргумент-указатель является двусторонним каналом передачи информации.) На втором выходе получаем код состояния, что обеспечивается функциейreturn. Отсюда следует, что "скелет" нашей функции должен выглядеть примерно так:

Поделиться с друзьями: