Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
231112.docx
Скачиваний:
4
Добавлен:
01.03.2025
Размер:
1.93 Mб
Скачать

Int main()

{

int times;

char ch;

cout << "Enter a character: ";

cin >> ch;

while (ch != 'q')

{

cout << "Enter an integer: ";

cin >> times;

n_chars(ch, times);

// функция с двумя аргументами

cout << "\nEnter another character or press the"

"q-key to quit: "; // ввод другого символа или q для завершения

cin >> ch;

cout << "The value of times is " << times << ".\n"; // вывод значения переменной times cout « "Bye\n"; return 0;

}

getchar();

getchar();

return 0;

}

void n_chars(char c, int n) {

while (n-- > 0) cout << c;

// вывод значения с n раз // продолжение, пока n не достигнет 0

}

Функция main () в листинге 7.3 использует цикл while для организации повторяющегося ввода. Обратите внимание, что для чтения символа в ней применяется cin » ch, а не cin. get (ch) или ch = cin. get (). На то имеется серьезная причина. Вспомните, что две функции cin.get () читают все входные символы, включая пробелы и символы новой строки, в то время как cin » пропускает пробелы и символы новой строки. Когда вы отвечаете на приглашение к вводу в программе, то должны нажимать <Enter> в конце каждой строки, генерируя тем самым символ новой строки. Подход cin » ch пропускает эти лишние символы, тогда как оба варианта с in. get () читают символ новой строки, следующий за каждым введенным числом, как очередной символ для отображения. Этот нюанс можно обойти программным путем, но проще использовать cin, как это делается в программе из листинга 7.3.

Функция n_chars () принимает два аргумента: символ с и целое число n. Затем в цикле она отображает символ столько раз, сколько указано в n:

while (n-- > 0) // продолжение, пока n не достигнет 0

cout << с;

Обратите внимание, что программа выполняет подсчет, уменьшая на каждом шаге значение переменной n, которая является формальным параметром из списка аргументов. Этой переменной присваивается значение переменной times в main (). Цикл while уменьшает n до 0, но, как демонстрирует пример выполнения, изменение значения n никак не отражается на значении times. Даже если в main () вместо имени times использовать имя n, значение n в main() не затрагивается изменениями значения п в n_chars ().

Еще одна функция с двумя аргументами

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

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

Для начала нам понадобится формула. Если вы должны угадать 6 значений из 51, математики говорят, что у вас имеется один шанс выигрыша из R, где R вычисляется по следующей формуле:

Для шести чисел в знаменателе будет произведение первых шести целых чисел, или 6!. Числитель же вычисляется как произведение шести последовательных чисел, на этот раз начинающихся с 51 и ниже. В общем, если нужно выбрать picks значений из numbers чисел, то числителем будет факториал для picks, а знаменателем — произведение picks целых чисел, начиная со значения numbers и ниже.

Для выполнения этого вычисления можно воспользоваться циклом

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

(10 * 9) / (2 * 1)

и

(10 / 2) * (9 / 1)

Первое выражение вычисляется как 90/2 и дает в результате 45, а второе вычисляется как 5 х 9 с получением того же результата 45. Результаты одинаковы, но в первом случае получается большее промежуточное значение (90), нежели во втором. Чем больше множителей, тем существеннее будет разница. Для больших чисел эта стратегия замены умножения делением может предохранить процесс вычисления от переполнения максимально возможного значения с плавающей точкой.

В листинге 7.4 эта формула заключена в функцию probability (). Поскольку количество вариантов выбора и общее количество чисел должны быть положительными значениями, в программе для этих величин используется тип unsigned int (сокращенно — unsigned). Перемножение нескольких целых может породить достаточно большие результаты, поэтому в lotto.срр для возвращаемого значения функции применяется тип long double. К тому же такие выражения, как 49/6, порождают ошибки округления при работе с целочисленными типами.

// lotto.срр — вероятность выигрыша

#include <iostream>

// Примечание: некоторые реализации требуют применения double вместо long double

long double probability(unsigned numbers, unsigned picks);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]