DEVC++(1)单文件实现重载运算符的十六进制数类

2023-05-16

本文运用DEVC++软件,通过C++类的定义和重载运算符来实现十六进制数类的运算操作,代码以单文件的方式来构建。

题目描述如下:
设计1~4位的无符号十六进制数据类class HEX. 可以创建如 ABCD、1234、DF09、AB、26之类的1~4位的十六进制的正整数。可以输入输出十六进制数据,可以实现十六进制数据和十进制数据的互换,可以实现2个十六进制数据的+、-、*、/、%操作。

为实现上述目的,我们首先来构建主函数,在主函数的构建中,我们自然希望操作界面简洁友好,希望将十进制数的加减乘除操作自然而然的转移到十六进制数上,使输入输出一目了然,因而在后续的类的定义上要下一番功夫,也要用到运算符的重载。

int main()
{   HEX n1,n2,n3;
    char repeat('Y');
    do
    {   n1 = 0; n2 = 0; n3 =0;
        cin>>n1>>n2;  //n1,n2为十六进制数
        n3 = n1+n2;
        cout<<n1<<'+'<<n2<<'='<<n3<<endl;
        n3 = n1-n2;
        cout<<n1<<'-'<<n2<<'='<<n3<<endl;
        n3 = n1*n2;
        cout<<n1<<'*'<<n2<<'='<<n3<<endl;
        n3 = n1/n2;
        cout<<n1<<'/'<<n2<<'='<<n3<<endl;
        n3 = n1%n2;
        cout<<n1<<'%'<<n2<<'='<<n3<<endl;
        cout<<"Repeat?(Y/N)";
        cin>>repeat;
    }while(repeat=='Y'||repeat=='y');
    return 0;
}

由上面的主函数代码可以看到,加减乘除的命令符号沿用了十进制数的加减乘除,因而要对这些运算符在十六进制数类的范围下重载。此外,主函数设置了循环,只是为了方便重复测试。
下面来定义十六进制数类以及类的各种操作。特别要注意的一点是,因为在输入输出十六进制数时要访问类的成员,因而要在重载输入输出符时将其设置为友元。

#include <iostream>
#include <string>
#include <cmath>
#include <process.h>
using namespace std;
char Hex_num[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};              //十六进制数字符的取值范围,便于后续的转化操作
class HEX
{   char m_num[10];    //可以存放10位十六进制数据,这样可以确保2个4位十六进制数据+和*的结果不会溢出
public:
    HEX();                            //构造函数,初始化成全‘0’
    HEX(unsigned n);             //用无符号整数创建十六进制数据,(即无符号整数转换成十六进制数据)
    unsigned GetBit(int i);         //获得每一位数据的十进制数值
    operator unsigned();     //把十六进制数据转换成无符号的十进制数据
    int length();                        //获得数据的长度
    HEX operator+(HEX n);                //加法
    HEX operator-(HEX n);              //减法运算要求被减数不小于减数
    HEX operator*(HEX n);               //乘法
    HEX operator/(HEX n);               //整除,即只要得到商
    HEX operator%(HEX n);              //取模,即只要得到余数
    HEX& operator++();                   //前置++
    HEX operator++(int);                 //后置++
    friend istream & operator>>(istream &i, HEX& n); 
                                        // 输入十六进制数
    friend ostream & operator<<(ostream &o, HEX n);//输出十六进制数
};

上面只是类的申明,尤其是对运算只给出了一个基本框架,还须具体实现它,接下来就是对其的具体补充。
(1)默认构造函数

HEX::HEX()
{ memset(m_num,'0',sizeof(m_num));
}

(2) 重载构造函数,将十进制数转成十六进制数并以逆序存储

HEX::HEX(unsigned n)          //十六进制数字符以逆序存储,并以'\0'字符结束 
{ 
   HEX();
   int i=0,t,j=0;
   if(n>0)  //处理n>0的情况  
   while (n >0)
        {
            t=n%16; 
            m_num[i++]= Hex_num[t];
            n = n / 16;
        }
    else m_num[i++]='0';   //处理n=0的情况  
     m_num[i]='\0';
}

(3)获取每一位字符的十进制数值。主要思路,对读取的字符分两种情况处理,一种是A~F,一种是0~9,用其与A或0字符将字符转成数值,再根据所在位数(k),用 a×16k 作为返回结果。

unsigned HEX::GetBit(int i)  //从十六进制数的最低位算起,获取第i位数的十进制表示 
{  
   int a;
   if(m_num[i-1]>='A'&&m_num[i-1]<='F')
      a=m_num[i-1]-'A'+10;
   else 
      a=m_num[i-1]-'0';
   while(i>1)
        {
          a=a*16;
          i--;
        }
   return a;   
}

(4)利用GetBit(i)实现把十六进制数据转换成无符号的十进制数据

HEX::operator unsigned()      
{  
   int j=1;
   int b=0;
   for(;j<=10&&m_num[j-1]!='\0';j++) //判断字符是否结束
     b+=GetBit(j);    
   return b;
} 

(5)获得十六进制数的长度

int HEX::length()
{  return strlen(m_num);}

(6)重载‘+’运算符。对加减乘除运算符的重载主要是通过当前指针this和类型转换来实现的,即首先定义两个无符号整数变量a,b,然后通过类型转换将十六进制数转成十进制数,随后进行加减乘除运算,最后再通过调用构造函数把结果的数据类型转成十六进制。
这里之所以能够实现类型转换是因为前面定义了类型转换(4)HEX:: operator unsigned.

HEX HEX::operator+(HEX n)     //利用类型转换实现四则运算 
{ 
  unsigned a,b;
  a=*this;
  b=n;
  return HEX(a+b);
}

(7)‘-’运算符重载。想法与加法运算符重载基本一致,但是需要注意的是要先判断被减数是否大于减数,若大于则进行减法运算,反之报错。

HEX HEX::operator-(HEX n)
{  
  unsigned a,b;
  a=*this;
  b=n;
  if(a<b)
    cout<<"错误:被减数小于减数"<<endl;
  else  
    return HEX(a-b);
}

(8)‘*’,’/’,’%’运算符重载是平凡的,与加法是完全一致的,因而此处略去代码。
(9)实现前置++。想法是通过类型转换和this指针来实现。

HEX& HEX::operator++()
{   
    unsigned a=*this;
    *this=HEX(a+1);
    return (*this);
}

(10)实现后置++

HEX HEX::operator++(int)
{   
    HEX old=*this;
    ++(*this);
    return old;
}

(11)实现十六进制数的输入。由于十六进制数以逆序存储,所以输入数据时对其反转,并以’\0’字符结束 。

istream& operator>>(istream& i, HEX& n)           
{  
   cout<<"Please input a Hex number(>=0,<=FFFF,Hex characters:0-9 or A-F):"<<endl;
   char temp[10];
   i>>temp;
   int len=strlen(temp); //调用取长函数来寻找初始存储位置
   int j;
   for(j=0;j<len;j++)
   n.m_num[j]=temp[len-1-j];
   n.m_num[j]='\0';
   return i;
}

(12)实现十六进制数的输出。与输入类似,由于十六进制数以逆序存储,所以输出数据逆序输出。

ostream& operator<<(ostream& o, HEX n)         
{  
   int len=n.length();
   int j;
   for(j=0;j<len;j++)
   o<<n.m_num[len-j-1];
   return o;
}

结语:
到这里就结束啦,回顾一下,其实通过重载运算符实现十六进制数的运算的关键在于运用类型转换和this指针,还有就是要清楚自己所定义的十六进制数在计算机中存储的方式,本文采用的逆序存储,其实也可以采用顺序存储啦,只要自己清楚其存储方式,在用字符的时候不要搞错了就好啦。
完整的代码我也会上传供大家参考,这个是单文件的,后续会补一个多文件的。
http://download.csdn.net/detail/zhazhazl/9645690
代码的测试输出如下:
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DEVC++(1)单文件实现重载运算符的十六进制数类 的相关文章

随机推荐