Math++ 开发(2) - 分数类的编写

知识点

class的使用
c++重载操作符:operator
this指针
qc的基本使用
.ui文件
默认参数的使用

今天的源码

fraction.cpp

#include "fraction.h"

Fraction::Fraction(int a, int b)
{
    if (b == 0)
    {
        return;
    }
    this->a = a;
    this->b = b;
}

Fraction Fraction::operator+(Fraction ot)
{
    int _up, _down;
    _down = this->b * ot.b;
    _up = this->a * ot.b + ot.a * this-> b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

Fraction Fraction::operator-(Fraction ot)
{
    int _up, _down;
    _down = this->b * ot.b;
    _up = this->a * ot.b - ot.a * this-> b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

Fraction Fraction::operator*(Fraction ot)
{
    int _up, _down;
    _up = this->a * ot.a;
    _down = this->b * ot.b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

Fraction Fraction::operator/(Fraction ot)
{
    int _up, _down;
    _up = this->a * ot.b;
    _down = this->b * ot.a;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

int Fraction::measure(int x, int y)
{
    int z = y;
    while(x%y!=0)
    {
        z = x%y;
        x = y;
        y = z;
    }
    return z;
}

void Fraction::view(void)
{
    qDebug() << this->a << "/" << this->b << endl;
}

void Fraction::setA(int inp)
{
    this->a = inp;
}

void Fraction::setB(int inp)
{
    this->b = inp;
}

fraction.h

#ifndef FRACTION_H
#define FRACTION_H

#include <QDebug>

class Fraction
{
public:
    Fraction(int a=0, int b=1);
    Fraction operator+(Fraction ot);
    Fraction operator-(Fraction ot);
    Fraction operator*(Fraction ot);
    Fraction operator/(Fraction ot);
    void view(void);
    void setA(int inp);
    void setB(int inp);
    int a, b;
private:
    int measure(int x, int y);
};

#endif // FRACTION_H

过程详解

创建工程

qc - 文件 - 新建(ctrl+n)
弹出新建对话框
在这里插入图片描述
这不有手就行
在这里插入图片描述
这个qmake别去改它,
在这里插入图片描述
在这里插入图片描述
解释一下:class name是程序主类,暂且就叫MainWindow吧.
Base class:顾名思义,基类,也就是MainWindow要继承的类.
Header file:这个类的头文件
Source file:源文件
**最下面是重点:**那个复选框勾上.表示"从界面文件创建界面",也就是下面的mainwindow.ui,下面会做解释.
ok,下一步.
在这里插入图片描述
这个不管他.
在这里插入图片描述
这个建议都勾上,运行套件,编译用的.

最后,那个版本控制系统,加不加无所谓,最好加,我就用git,没毛病.

.ui文件解释

这玩意只能用qc解释,xml文档格式,用于储存"form",也就是所谓的"界面样式"
由于咱还是新手,不会纯代码编程,暂时用这个可视化的练练手吧…

(插个题外话,不是我瞎说,真的,用ui比纯代码快好多,特别是这种基本静态的界面)

主体编写

创建完后长这样:(因为是写完后才写的文章,所以嘛…)
在这里插入图片描述
右键项目名称,(在文件栏里),add new…
在这里插入图片描述
填一个类名:Fraction(分数)
多了两个文件:fraction.h和fraction.cpp(分别在HeadersSources里).
在这里插入图片描述
我们先复习一下:C++中,头文件中放声明,源文件中放实现,所以,在fraction.cpp中编写了成员函数等之后,一定要在fraction.h中声明.

首先,因为要在类外访问,所以存放分母(a),分子(b)的变量应放在public中.

int a, b;

类构造函数:Fraction::Fraction(int a=0, int b=0);

Fraction::Fraction(int a, int b)
{
    if (b == 0)
    {
        return;
    }
    this->a = a;
    this->b = b;
}

这里注意:数学中,分母不为零,所以b==0时直接返回.
接下来两行:分别将传入参数放进定义好的整型变量中.

而在头文件中,我们则这样声明:

Fraction(int a=0, int b=1);

注意到了吗?我们只在头文件成员函数定义中给出了默认值,而源文件中则不用,也不能,不然会报:在这里插入图片描述
重定义默认参数.

为了方便查看分数的状态,我们给出Fraction::view(void)

void Fraction::view(void)
{
    qDebug() << this->a << "/" << this->b;
}

QDebug是qt用于输出调试信息的,所以要包含头文件:

#include <QDebug>

要输出,则用插入操作符<<传给qDebug()

再定义两个设置函数

void Fraction::setA(int inp)
{
    this->a = inp;
}

void Fraction::setB(int inp)
{
    this->b = inp;
}

我们来测试一下.

//main.cpp
#include "mainwindow.h"
#include "fraction.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    //w.show();
    Fraction f1(12, 24);
    f1.view();
    Fraction f2(13, 43);
    f2.view();
    return a.exec();
}

ctrl+r运行,然后手动kill进程"mathplusplus.exe"得到如下:
在这里插入图片描述
接下来;编写操作符重载.先来个简单点的,乘和除.(乘->上乘上,下乘下, 除->上乘下作上)

Fraction Fraction::operator*(Fraction ot)
{
    int _up, _down;
    _up = this->a * ot.a;
    _down = this->b * ot.b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

Fraction Fraction::operator/(Fraction ot)
{
    int _up, _down;
    _up = this->a * ot.b;
    _down = this->b * ot.a;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

大概了解原理后,可以写出+和-:

Fraction Fraction::operator+(Fraction ot)
{
    int _up, _down;
    _down = this->b * ot.b;
    _up = this->a * ot.b + ot.a * this-> b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

Fraction Fraction::operator-(Fraction ot)
{
    int _up, _down;
    _down = this->b * ot.b;
    _up = this->a * ot.b - ot.a * this-> b;
    int cand = this->measure(_up, _down);
    return Fraction(_up / cand, _down / cand);
}

测试一下:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    //w.show();
    Fraction f1(1, 4);
    f1.view();
    Fraction f2(1, 3);
    f2.view();
    (f1 * f2).view();
    (f1 / f2).view();
    (f1 + f2).view();
    (f1 - f2).view();
    //return a.exec();
    return 0;
}
20:36:10: Starting D:\Program Files\Projects\build-mathplusplus-Desktop_Qt_5_9_9_MinGW_32bit-Debug\debug\mathplusplus.exe ...
1 / 4
1 / 3
1 / 12
3 / 4
7 / 12
1 / -12
20:36:10: D:\Program Files\Projects\build-mathplusplus-Desktop_Qt_5_9_9_MinGW_32bit-Debug\debug\mathplusplus.exe exited with code 0

差点忘了,还有一个重要的成员函数measure,最小公约数,用于约分.

int Fraction::measure(int x, int y)
{
    int z = y;
    while(x%y!=0)
    {
        z = x%y;
        x = y;
        y = z;
    }
    return z;
}

总结

今天我们编写了分数 类,为什么?

数学是严谨的,容不得半点马虎.

c++提供的double,float,都有精确度的问题,而且数学中的分数大多转换成小数无限循环,多次计算,然后取近似数,久而久之,精确度就像照相机"一米之外人畜不分",这显然不是我们想要的,所以就有了这个类.

项目是久而久之累积起来的,每一个组件,模块都要精心设计,精心编写.当我们认真对待每一句代码时,学习效果,作品,总能回报付出!

03-16
相信大家都用过window自带的计算器。它存在如下不足: 1. 当你输入一个长的式子时,在中途出错就不得不从头再来。 2. 没有变量定义。 3. 输入不直观。如要算 cos(pi) 时,你要先按 pi ,再按 cos ,相当不便。 本软件正是针对上面的问题而开发的。以下为软件的使用说明。 ㈠ 运算符 +-*/^% 优先级 : 由低至高 (同级间按在表达式中从左到右的顺序运算) + - * / ^(幂) %(求余) ㈡ 函数 rad(x)表示求x的弧度。如 rad(90) = pi/2 deg(x)表示求x的度数。如 deg(pi/4) = 45 ln(x) 表示求x的自然对数。 lg(x) 表示以10为底x的对数。 log(x,y)表示以x为底y的对数。 exp(x)表示e的x次方。 sqrt(x)表示x的平方根。 abs(x)表示x的绝对值。 min(x,y)表示求x,y中的最小值。 max(x,y)表示求x,y中的最大值。 mod(x,y)表示求x/y的余数。 floor(x)表示不大于x的最大整数。 pow(x,y) 与 x^y 相同, pow( 8,1/3) 等价于 8^(1/3)。 三角函数 sin,cos,tan,ctg,sinh,cosh,tanh。 反三角函数 asin,acos,atan。 ㈢ 自定义变量 变量名:以字母开头,其余部分为字母、数字、下划线的组合,且不能为";;;reset";;;。 ㈣ 运算结果变量 ans为每次运算的默认结果变量, 如:";;;3-7";;;将使得ans=-4;;;; 也可以若指定运算结果变量, 如: 输入";;;x=3-7";;;将使得x=-4。 ㈤ 内置变量 pi=3.141592653589793 e =2.718281828459045 当你改变了pi或e的默认值时(如";;;pi=6";;;),可键入";;;reset";;;重置。 ㈥ 其它 在进行 x^y或pow(x,y) 运算时,若x<;;;0且y的绝对值少于1则报错,但事实上不一定就有错。 三角函数中的参数是以弧度计的。 在输入数字时,如";;;2.3*10^100";;;可用";;;2.3e100";;;代替(即科学记数法)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dtsroy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值