Структуры, описание рационального числа - C (СИ)
Формулировка задачи:
Ввести структуру с полями «числитель» и «знаменатель» для описания понятия «рациональное число». Составить и протестировать функции:
– ввода и вывода на экран рационального числа;
– сокращения рационального числа;
– вычисления произведения двух рациональных чисел.
Никак не работает 2 и 3 функции. Все вроде правильно. Выводит абсолютно неверные числа, особенно в знаменателе, хотя бывает и числитель глючит.
Название переменной Тип Назначение
Входные данные
s int переключающее выражение
chr struct структура для хранения числителя и знаменателя дроби
ch.numerator int элемент структуры chr для хранения числителя
ch.denominator int элемент структуры chr для хранения знаменателя
Выходные данные sokr(ch) struct структура для хранения числителя и знаменателя сокращенной дроби
chr_rez struct структура для хранения числителя и знаменателя дроби, полученной в результате произведения двух дробей
#include <stdio.h>
#include <conio.h>
#include <iostream>
struct chislo
{
unsigned int chislitel, znamenatel;
};
chislo ch;
void io ()
{
printf("Введите числитель ");
scanf("%d", &ch.chislitel);
printf("Введите знаменатель ");
scanf("%d", &ch.znamenatel);
if (ch.znamenatel==0)
{
printf("На 0 делить нельзя, введите другой знаменатель\n\n");
io();
}
else
printf("\n\n%d/%d\n\n", ch.chislitel, ch.znamenatel);
}
chislo sokr(chislo ch)
{
chislo ch_sokr;
if (ch.chislitel==ch.znamenatel)
{
ch_sokr.chislitel=1;
ch_sokr.znamenatel=1;
}
if (ch.chislitel<ch.znamenatel){
for(int i=ch.chislitel; i>=2; i--)
{
if(ch.chislitel%i==0 && ch.znamenatel%i==0)
{
ch_sokr.chislitel=ch.chislitel/i;
ch_sokr.znamenatel=ch.znamenatel/i;
break;
}
else
{
ch_sokr.chislitel=ch.chislitel;
ch_sokr.znamenatel=ch.znamenatel;
}
}
}
else
for(int i=ch.znamenatel; i>=2; i--)
{
if(ch.chislitel%i==0 && ch.znamenatel%i==0)
{
ch_sokr.chislitel=ch.chislitel/i;
ch_sokr.znamenatel=ch.znamenatel/i;
break;
}
else
{
ch_sokr.chislitel=ch.chislitel;
ch_sokr.znamenatel=ch.znamenatel;
}
}
return(ch_sokr);
}
chislo proizv()
{
chislo ch1, ch2, ch_rez;
io();
ch1=ch;
io();
ch2=ch;
ch_rez.chislitel=ch1.chislitel*ch2.chislitel;
ch_rez.znamenatel=ch1.znamenatel*ch2.znamenatel;
return(ch_rez);
}
int main()
{
setlocale(0, "Russian");
int s=0, n;
do
{
printf("Выберите функцию:\n");
printf("1 - Ввод/вывод числа\n");
printf("2 - Сокращение числа\n");
printf("3 - Произведение двух чисел\n");
scanf("%d", &s);
switch (s)
{
case 1: io(); break;
case 2: {io(); printf("Сокращенная дробь = %d/%d", sokr(ch)); break;}
case 3: printf("Произведение дробей = %d/%d", proizv()); break;
default: printf("Такой ф-ии не существует"); break;
}
}
while (s<1 && s>3);
getch();
}Решение задачи: «Структуры, описание рационального числа»
textual
Листинг программы
#include <stdlib.h>
int gcd(int a, int b) { // НОД алгоритм Эвклида
int t;
while (b != 0) {
t = b;
b = a % b;
a = t;
}
return a;
}
chislo Reduction (chislo ch) { // лучше использовать англоязычные названия для всего, транслит невозможно читать и тяжело писать
chislo ans;
unsigned divisor;
if (ch.znamenatel == 0 ){
printf("O-ops, devided by zero, aborting execution ! \n");
exit (-1);
}
if (ch.chislitel == 0 ){
ans.chislitel = ans.znamenatel = 0;
return ans;
}
if (ch.chislitel == ch.znamenatel){
ans.chislitel = 1;
ans.znamenatel = 1;
return ans;
}
else {
divisor = gcd (ch.chislitel, ch.znamenatel) ;
ans.chislitel /= divisor;
ans.znamenatel /= divisor;
return ans;
}
Объяснение кода листинга программы
- Программа находит наибольший общий делитель (НОД) двух целых чисел с помощью алгоритма Эвклида.
- Если делитель равен нулю, программа выводит сообщение об ошибке и завершает работу.
- Если делитель и числитель равны нулю, программа возвращает ноль.
- Если делитель равен числителю, программа возвращает единицу.
- В противном случае программа находит наибольший общий делитель числителя и знаменателя, затем делит числитель на этот делитель и знаменатель на этот делитель.
- Возвращает полученные результаты.