Задача 9.1. Составить программу вычисления c = n! / (m! * (m-n)!)
В вычисляемом выражении требуется трижды вычислять факториал вида k!, где k! = 1*2*...*k при целом k > 0, 0! = 1.
Вычисление факториала удобно оформить как подпрограмму.
Решение А. Использование подпрограммы, не возвращающей значение.
Пусть вызов подпрограммы p_fakt (k, f) обозначает действие - операцию присваивания f = k!;. Здесь k - исходные данные, а f - результат. Таким образом, подпрограмма p_fakt() имеет входной параметр k и выходной параметр f.
Обозначим факториалы: n!, m! и (n-m)! через f1, f2 и f3, соответственно. Получим программу 9.1а.
Подпрограмма вычисления факториала p_fakt содержит повторение умножений, т. е. имеет циклическую структуру. Текущим множителем служит вспомогательная переменная j, изменяющаяся с шагом +1.
/* Программа 9.1а. Вычисление c=n!/(m!*(m-n)!) */
/* с помощью подпрограммы, не возвращающей значение */
# include <stdio.h>
void p_fakt (int k, long *f); /* прототип функции */
/* Вычисление c = n! / (m! * (n-m)!) */
void main(void)
{ int n, m, c; /* исходные данные и результат */
|
|
long f1, f2, f3; /* n!, m!, (n-m)! */
printf("\nВведите два исходных целых числа ");
scanf("%d %d", &n, &m);
p_fakt (n, &f1); /* f1 = n! */
p_fakt (m, &f2); /* f2 = m! */
p_fakt (n-m, &f3); /* f3 = (n-m)! */
c = f1 / (f2 * f3);
printf ("\n c = %d", c);
}
/* Подпрограмма: f = k!; */
void p_fakt (int k, long *f)
{ int j; /* текущий множитель */
*f=1;
for (j=2; j<=k; j++)
*f = (*f)* j;
return; /* здесь не обязателен */
}
/* Программа 9.1б. Вычисление c=n!/(m!*(m-n)!) */
/* с помощью функции, возвращающей значение */
#include <stdio.h>
long fakt (int k); /* прототип функции */
/* Вычисление c = n! / (m! * (n-m)!) */
void main(void)
{ int n, m, c; /* исходные данные и результат */
printf("\nВведите два исходных целых числа ");
scanf("%d %d", &n, &m);
c = fakt(n) / (fakt (m) * fakt (n-m));
printf ("\n c = %d", c);
}
/* Функция k! */
long fakt (int k)
{ long f; /* k! */
int j; /* текущий множитель */
f=1;
for (j=2; j<=k; j++)
f = f * j;
return f; /* значение функции */
}
Пояснения к программам.
1. В программах 9.1а, 9.1б вызовы подпрограмм расположены в тексте программы раньше, чем определения этих подпрограмм. Поэтому в начале программы объявлены функции, т.е. записаны их прототипы.
2. В программе 9.1б результат работы подпрограммы fakt передается как значение функции. Поэтому переменная f является не параметром, а вспомогательной локальной переменной и записывается без звездочки.
3. В программе 9.1а вызов функции p_fakt, не обладающей значением, может записываться только как самостоятельный оператор. В программе 7.1б вызов функции fakt, обладающей значением, может являться операндом в выражении.
4. В программе 9.1а при выводе результата можно заменить строки:
c = f1 / (f2 * f3);
printf ("\n c = %d", c);
строкой:
printf ("\n c = %d", f1/(f2*f3));
Тогда переменная c и ее объявление становятся ненужными. В программе 9.1б также можно обойтись без переменной с.
|
|
Схемы для каждой функции рисуются отдельно. Для данной программы нужно изобразить две схемы: для главной функции main и для функции fakt. Для подпрограмм в начальном блоке пишется имя функции, а в конечном - слово “возврат” с возвращаемым значением (если функция значение не возвращает, то просто слово “возврат”). Ниже приведены схемы для программы 9.1б.
Задача 9.2. Даны две строки длиной до 80 символов. Определить число латинских букв в каждой строке.
/* Программа 9.2 */
#include <stdio.h>
/*----------------------------------------------------------------------------------*/
/* Функция определения количества лат. букв в заданной строке */
/*----------------------------------------------------------------------------------*/
int KolLatBukv (char s[])
{
int i, /* индекс очередного символа строки s */
k=0; /* количество лат. букв */
for (i = 0; s[i]!= '\0'; i++)
if (s[i] >= 'a' && s[i] <= 'z' | | s[i] >= 'A' && s[i] <= 'Z') k++;
return k;
}
/*------------------------*/
/* Главная функция */
/*------------------------*/
void main()
{
char s1[81], s2[81]; /* заданные строки */
printf ("\nВведите две строки символов\n");
gets (s1);
gets (s2);
printf ("В 1-й строке %d лат. букв\n", KolLatBukv (s1));
printf ("Во 2-й строке %d лат. букв\n", KolLatBukv (s2));
}
Пример результата выполнения программы:
Введите две строки символов
AaBbcd 123 Zz
t = x + y * z / 10;
В 1-й строке 8 лат. букв
Во 2-й строке 4 лат. букв
Задача 9.3. Описать функцию, которая для заданного числового массива определяет сумму и количество положительных элементов.
/* Программа 9.3 */
#include <stdio.h>
/*------------------------------------------------------------------*/
/* Функция определения суммы и количества */
/* положительных элементов заданного массива */
/*------------------------------------------------------------------*/
void SumPos (float m[], int n, float *s, int *k)
/* Вх. параметры:
m – указатель на заданный массив,
n – число элементов массива.
Вых. параметры:
*s – сумма положительных элементов массива,
*k – количество положительных элементов */
{
int i;
for (i=0, *s=0, *k=0; i<n; i++)
if (m[i] > 0) (*s) += m[i], (*k)++;
}
/*---------------------------------------------------------------------*/
/* Главная функция (для тестирования подпрограммы) */
/*---------------------------------------------------------------------*/
void main()
{
float a[6], /* массив */
s; /* сумма положительных элементов */
int k, /* количество положительных эл-тов */
i; /* индекс элемента массива*/
printf ("\nВведите 6 чисел\n");
for (i=0; i < 6; i++) scanf ("%d ", &a[i]);
SumPos (a, 6, &s, &k); /* вызов функции */
printf ("Сумма положительных чисел = %f\n", s);
printf ("Количество положительных чисел: %d\n", k);
}