Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 5.00/58: Рейтинг темы: голосов - 58, средняя оценка - 5.00
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48

Создать класс с именем Rational для выполнения арифметических действий с дробями

24.07.2011, 23:33. Показов 12113. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте!
подскажите пожалуйста в чем ошибка?
по задаче мне нужно создать класс с именем Rational для выполнения арифметических действий с дробями. для представления закрытых членов данных класса (числителя и знаменателя) )нужно использовать целые переменные. надо создать функцию конструктор, которая позволяет объекту класса принимать начальные значения при его объявлении(конструктор должен также содержать значения по умолчанию). конструктор должен хранить дроби в сокращенном виде (т.е. дробь 2/4 должна храниться в объекте как 1 в числителе и 2 в знамнателе). нужно создать открытые функции-члены для каждой арифметической операции.
мой код не корректно работает если знаменатели задаются нулевым значением, почему так?
вот код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include<iostream.h>
#include<time.h>
#include<conio.h>
#include<stdio.h>
#include<iomanip.h>
#include<math.h>
using std::setfill;
using std::setw;
using namespace std;
 
class Rational
{
public:
 Rational(int =1,int =1,int =1,int =1);
 void setRational(int ,int ,int ,int );
 int Plus(/*int ,int, int, int */);
 void Print1();
private:
 int ch1,ch2;
 int zn1,zn2;
 int rez_ch1,rez_zn1;
};
 
Rational::Rational(int a1,int b1,int a2,int b2)
{
 setRational(a1,b1,a2,b2);
}
 
void Rational::setRational(int aa1,int bb1, int aa2, int bb2)
{
ch1=aa1;
ch2=aa2;
if (bb1==0)
  {cout<<"ERROR, \n";
   while (bb1==0)
     {
     cout<<"set right value: ";
     cin>>bb1;
     }
  }
else zn1=bb1;
if (bb2==0)
  {cout<<"ERROR, \n";
   while (bb2==0)
     {
     cout<<"set right value: ";
     cin>>bb2;
     }
  }
else zn2=bb2;
}
 
int Rational::Plus()
{
rez_ch1=ch1*zn2+ch2*zn1;
rez_zn1=zn1*zn2;
return rez_ch1,rez_zn1;
}
 
void Rational::Print1()
{
cout<<rez_ch1<<"/"<<rez_zn1;
}
 
int main()
{
Rational r(1,0,3,4);
r.Plus();
r.Print1();
 
getch();
return 0;
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.07.2011, 23:33
Ответы с готовыми решениями:

Создайте класс с именем Rational для выполнения действий с дробями
Задание : создайте класс с именем Rational для выполнения действий с дробями и программу тестирования вашего класса. (используйте закрытые...

Создайте класс с именем Complex для выполнения арифметических действий с комплексными числами
В Общем программу написал, складывает-вычитает, но преподаватель требует в нее добавить класс комплексных чисел, не знаю как #include...

Создать класс Rational для работы с рациональными дробями
Рациональная (несократимая) дробь представляется парой целых чисел (а, b), где а — числитель, b — знаменатель. Создать класс Rational для...

20
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
24.07.2011, 23:42
А в чем именно заключается ошибка?
P.S. Как мне подсказывает мой трехлетний аспирантский опыт преподавания, с таким подходом к реализации классов Вы никогда не сдадите эту задачу... Не обижайтесь, но это ужас
0
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48
24.07.2011, 23:51  [ТС]
вы бы не могли пояснить в чем именно ужас?
ошибка в том, что если задавать числители и знаменатели числами отличными от нуля, то результат правильный. если задать один из знаменателей нулем, то получается ерунда.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
24.07.2011, 23:54
Цитата Сообщение от aquarius-a Посмотреть сообщение
if (bb2==0)
{cout<<"ERROR, \n";
while (bb2==0)
{
cout<<"set right value: ";
cin>>bb2;
}
}
else zn2=bb2;
если значение правильное оно присваивается
а Если не правильное???
ты прсишь ввести правильное и тут же его теряешь!
выбрось else
C++
1
2
3
4
5
6
7
8
9
10
if (bb2==0)
 {
    cout<<"ERROR, \n";
       while (bb2==0)
     { 
        cout<<"set right value: ";
        cin>>bb2;
     }
 }
 zn2=bb2;
еше лучше выбрось if
C++
1
2
3
4
5
6
 while (bb2==0)
 {
 cout<<"set right value: ";
 cin>>bb2;
 }
 zn2=bb2;
1
24.07.2011, 23:56

Не по теме:

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

0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
24.07.2011, 23:56
Цитата Сообщение от aquarius-a Посмотреть сообщение
return rez_ch1,rez_zn1;
как ты собираешься вернуть ДВА значения???
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
24.07.2011, 23:58
Цитата Сообщение от aquarius-a Посмотреть сообщение
Rational(int =1,int =1,int =1,int =1);
браво!
0
Добрый самаритянин
 Аватар для John_Pa9JIbHuK
1107 / 622 / 139
Регистрация: 31.03.2009
Сообщений: 2,567
25.07.2011, 00:00
Добавлено через 35 секунд
Цитата Сообщение от ValeryS Посмотреть сообщение
как ты собираешься вернуть ДВА значения???
Уличную магию еще никто не отменял =)
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
25.07.2011, 00:00
Ужас в том, что класс Rational должен содержать представление одного числа, а не трех.
Примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Rational
{
public:
  Rational(int a = 0, int b = 1);
  Rational plus(Rational r);
private:
  int ch;
  int zn;
};
 
Rational Rational::plus(Rational r)
{
  return Rational(r.ch * zn + r.zn * ch, r.zn * zn);
}
И гляньте совет ValeryS, он абсолютно верный.

P.S. Как уже упоминалось выше, арифметические операции обычно реализуют с помощью перегрузки операторов
Кстати, ввод/вывод объекта Rational тоже неплохо бы реализовать как перегрузку операторов <<, >>
0
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48
25.07.2011, 00:09  [ТС]
ValeryS, спасибо
насчет возврата двух значений я гоню.
to alex_x_x, если мне нужно задать значения по умолчанию и я написал Rational(int =1,int =1,int =1,int =1); это ошибочно?
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
25.07.2011, 00:13
Цитата Сообщение от soft.creator Посмотреть сообщение
Ужас в том, что класс Rational должен содержать представление одного числа, а не трех.
тогда ему нужно создать конструктор копирования
переопределить сложение,вычитание,умножение,деление, присваивания, может быть возведение в степень
и получится хороший классик для последующей работы а не для сдачи лаб
Цитата Сообщение от aquarius-a Посмотреть сообщение
конструктор должен хранить дроби в сокращенном виде (т.е. дробь 2/4 должна храниться в объекте как 1 в числителе и 2 в знамнателе).
совершенно не видно нормализации дроби
можно сделать так
вычисляем остаток от деления если его нет смело делим(а ну надо вычислить обший делитель)
но как быть с неправильными дробями и в частности с такими 5/1
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
25.07.2011, 00:15
Цитата Сообщение от aquarius-a Посмотреть сообщение
если мне нужно задать значения по умолчанию и я написал Rational(int =1,int =1,int =1,int =1); это ошибочно?
просто я поражен, что это возможно, такая запись
0
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48
25.07.2011, 00:22  [ТС]
to alex_x_x: подшучиваете?
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
25.07.2011, 00:24
Цитата Сообщение от alex_x_x Посмотреть сообщение
просто я поражен, что это возможно, такая запись
Запись сама по себе корректная. Но человеку, читающему программу, два числителя и знаменателя сломают мозг

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
тогда ему нужно создать конструктор копирования
переопределить сложение,вычитание,умножение,деление, присваивания, может быть возведение в степень
и получится хороший классик для последующей работы а не для сдачи лаб
Конструктор копирования такому классу не нужен - компилятор тут сам справится.
А вариант реализации сложения я написал. Остальные можно сделать по аналогии.
А насчет наибольшего общего делителя, Вы, конечно, правы.
0
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48
25.07.2011, 00:26  [ТС]
to ValeryS: нормализацию дроби я еще не дописал, так как споткнулся о вышеуказанную ошибку.
вы бы не могли объяснить, что значит конструктор копирования? и что значит "класс Rational должен содержать представление одного числа, а не трех"?
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
25.07.2011, 00:44
Цитата Сообщение от aquarius-a Посмотреть сообщение
to ValeryS: нормализацию дроби я еще не дописал, так как споткнулся о вышеуказанную ошибку.
вы бы не могли объяснить, что значит конструктор копирования? и что значит "класс Rational должен содержать представление одного числа, а не трех"?
Про конструктор копирования пока не забивайте себе голову, хотя будет время - обязательно почитайте. Очень хорошо объяснено в "C++ для чайников" Дэвиса, не пугайтесь названия книги, она очень толковая.

А по поводу трех постараюсь объяснить - это принципиальный момент. Смотрите.
С точки зрения реального мира или предметной области рациональное число - это отношение числителя к знаменателю. Экземпляр (ну, просто отдельная переменная) класса Rational должен моделировать одно рациональное число. Поэтому внутри класса Rational, который я привел как пример, есть только один числитель и знаменатель.
В Вашем же варианте один класс Rational хранит внутри данные двух исходных чисел и одного результата, то есть фактически три числителя и три знаменателя. Недостатки такого подхода:
- Любой, кто будет разбираться в Вашем коде, будет вынужден выяснять, какое поле к чему относится. А код должен быть понятен читающему.
- Ваш класс пытается решить слишком много задач сразу. Тут и ввод значения знаменателя, если он нулевой, и хранение двух исходных чисел, и хранение результата.
- К тому же, Ваш вариант годится только для решения одной конкретной задачи. А если на сдаче лабы препод попросит сложить два числа и умножить их на третье? Я бы попросил

Если Вы обратите внимание, как реализована функция plus у меня, она просто принимает на вход другое рациональное число, формирует третье и возвращает его как результат. Как видите, здесь все достаточно просто написано и понятно любому читающему. К тому же, можно строить таким образом сложные выражения, наподобие:
C++
1
2
3
4
Rational a, b, c, d;
// ... вводим a, b, c ...
Rational tmp = a.plus(b);
d = tmp.mult(c);
Получаем d = (a+b)*c
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
25.07.2011, 00:50
Цитата Сообщение от aquarius-a Посмотреть сообщение
что значит конструктор копирования?
это значит конструктор копирования
т.е ты можешь создать такую запись
C++
1
2
Rational r(1,0,3,4);
Rational r1(r);
и получишь два полностью похожих объекта
если переопределишь операцию присвоения
то сможешь написать так
C++
1
Rational r1=r
но насчет конструктора копирования для такого простенького класса soft.creator, прав

Цитата Сообщение от soft.creator Посмотреть сообщение
Конструктор копирования такому классу не нужен - компилятор тут сам справится.
Цитата Сообщение от aquarius-a Посмотреть сообщение
что значит "класс Rational должен содержать представление одного числа, а не трех"?
это значит ты не разобрался с классами не понял зачем они нужны
в классе Rational всего два члена числитель и знаменатель(может быть третий для целого при нормализации неправильной дроби)
а ты впихнул туда всю структуру программы только зачем то описал классом (а если надо будет сложить 3 дроби? всю программу переписывай)

смотри пример от soft.creator
тогда ты сможешь работать с этим классом как захочешь
например так
C++
1
2
3
4
Rational r(1,0);
Rational r1(3,4);
Rational r2(2,4);
Rational r3=r+r1-r2;
0
0 / 0 / 1
Регистрация: 16.04.2011
Сообщений: 48
25.07.2011, 00:56  [ТС]
soft.creator, а вы бы не могли закоментировать ваш пример кода, у меня скорее мозги сломаются, чем я его пойму. допустим мне непонятно: вы пишете в public: Rational plus(Rational r).
насколько я понимаю перед функцией должен находиться тип возвращаемого значения (void, int, char и т.д.), а у вас стоит класс Rational - как это? и в списке параметров функции Plus вы указываете объект класса Rational? вот это тоже непонятно:
C++
1
2
3
4
Rational Rational::plus(Rational r)
{
  return Rational(r.ch * zn + r.zn * ch, r.zn * zn);
}
0
 Аватар для soft.creator
106 / 106 / 11
Регистрация: 17.10.2010
Сообщений: 283
25.07.2011, 01:00
В языке C++ есть встроенные типы данных (int, float и т.д.), а есть определяемые пользователем (это как раз наш класс Rational). И те, и другие можно равноправно применять при передаче параметров в функции и возврате значений из них. Кстати, класс string языка C++ - это тоже определяемый пользователем тип, просто добрые дяди его предоставили нам совершенно безвозмездно, т.е. даром (C).

Больше того, для класса Rational можно даже самостоятельно определить все математические операторы, и даже операторы вывода в поток и чтения из потока, тогда он будет практически неотличим от встроенных типов. Хотя это несколько выходит за рамки вашей лабораторки.

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

P.S. В стандартной библиотеке C++ есть класс complex - это реализация комплексного числа. Он как раз позволяет делать все то, что я написал выше. И его совершенно свободно можно передавать в функции и возвращать из них. Цель Вашей лабы - научить вас создавать собственные типы данных C++. Я же пытаюсь подсказать Вам, как это лучше сделать с точки зрения профессионального программиста С++
1
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,852
25.07.2011, 01:02
Цитата Сообщение от aquarius-a Посмотреть сообщение
возвращаемого значения (void, int, char и т.д
он и возвращает т.д т.е класс
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.07.2011, 01:02
Помогаю со студенческими работами здесь

Создать класс Rational для работы с рациональными дробями
Рациональная (несократимая) дробь представляется парой целых чисел (а, 6), где а — числитель, Ь — знаменатель. Создать класс Rational для...

Пример арифметических действий с обыкновенными дробями
арифметическое действие над обыкновенными дробями . кто-нибудь подскажет одно действие, дальше я сам. с применением класса

Написать программу для выполнения простейших арифметических действий
Вот, дали задание сделать прогу для выполнения простейших арифметических действий, а почему-то не компилируется и не компонуется... я уж не...

С++ класс (создайте класс с именем Complex для выполнения в арифмитических операий с комплексными числами))
Кто сможет помогите пожалуйста! (Класс Complex). Создайте класс с именем Complex для выполнения в арифмитических операий с...

Создать класс для работы с дробями
МОЖНО ТОЛЬКО НЕ КИТАЙСКИМ КОДОМ(хочу разобраться,не понимаю).заранее благодарен! Реализуйте класс Дробь. Необходимо хранить числитель...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru