1. 程式人生 > >DEVC++(1)單檔案實現過載運算子的十六進位制數類

DEVC++(1)單檔案實現過載運算子的十六進位制數類

本文運用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
程式碼的測試輸出如下:
這裡寫圖片描述

相關推薦

DEVC++(1)檔案實現過載運算子

本文運用DEVC++軟體,通過C++類的定義和過載運算子來實現十六進位制數類的運算操作,程式碼以單檔案的方式來構建。 題目描述如下: 設計1~4位的無符號十六進位制資料類class HEX. 可以建立如 ABCD、1234、DF09、AB、26之類的1~4

DEVC++(2)多檔案實現過載運算子

前一篇博文討論了用單檔案的方式實現過載運算子的十六進位制數類,在C++的實際應用中,人們傾向於使用多個檔案,用.h檔案來存放類的基本定義,用.cpp檔案來存放類函式的具體實現,最後在主函式中通過呼叫來實現最終目標。這種做法非常的實際,一方面在實際工程中,我們有時

編寫一個函式實現轉換。在主函式中輸人一個十進位制,輸出相應的。要求用陣列實現

void decto16 (int a, char c[]) {  // a為要轉換的十進位制數 將結果存放在陣列c中 ,以陣列形式輸出   int y;   int k = 0;   do {     y = a % 16;     a = a / 16;     for (int i = 0

檔案資料轉生成陣列

#include <stdio.h> #include <string.h> /* * feof():當設定了與流關聯的檔案結束識別符號時,該函式返回一個非零值,否則返回零

之間的轉換(1)——十進位制向二/八/的轉換

1.十進位制轉換為十六/八進位制 #define _CRT_SECURE_NO_WARNINGS //為解決scanf函式不安全的警告問題 #include<stdio.h> #include<stdlib.h> int main() { int i; //基本變

java實現二進位制轉

題目連結: 描述:輸入一個2進位制的數,要求輸出該2進位制數的16進製表示。在16進位制的表示中,A-F表示10-15輸入:第1行是測試資料的組數n,後面跟著n行輸入。每組測試資料佔1行,包括一個以

Perl實現十進位制和的轉換

從十進位制轉為十六進位制:vim d2h.pl#!/usr/bin/perl # Convert list of decimal numbers into hex for ($i=0;$i<@ARGV;$i++){ printf("%d\t=0x

JS實現隨機生成顏色值的程式碼

                       function getColor(){                           //定義字串變數colorValue存放可以構成十六進位制顏色值的值                           var colorValue="0,1,2,3,

組合語言實現輸入一個四二進位制輸出

DATAS SEGMENT     string db 'please input four char between 0 and f(hex):$'     ;此處輸入資料段程式碼   DATAS ENDS STACKS SEGMENT     ;此處輸入堆疊段程式碼 S

輸出和佔位

十六進位制數輸出和佔位 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 輸入一個整數,請你按如下要求輸出: 第一行按原樣輸出, 第二行以十六進位制輸出(字母小寫), 第三行以

String與互轉

  /***將字串轉換16進位制**/   public String toHexString(String jsonStr){            byte[] bytes=

字元轉對應的

#include <stdio.h> #include <string.h> /* C 庫函式 int feof(FILE *stream) 測試給定流 stream 的檔案結束識別符號。 */ int main( void ) { unsigned c

組合語言:將主程式中BX暫存器內的二進位制的形式在螢幕上顯示出來。

上機程式碼:   code segment       assume cs:code   start:       mov bx,1234H  

405.數字轉換為

給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。對於負整數,我們通常使用 補碼運算 方法。 注意: 十六進位制中所有字母(a-f)都必須是小寫。 十六進位制字串中不能包含多餘的前導零。如果要轉化的數為0,那麼以單個字元'0'來表示;對於其他情況,十六進

【LeetCode 簡單題】90-數字轉換為

宣告: 今天是第90道題。給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除 (手動比心ღ( ´・ᴗ・` )) 正文 題目:給定

領釦(LeetCode)數字轉換為 個人題解

給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。對於負整數,我們通常使用 補碼運算 方法。 注意: 十六進位制中所有字母(a-f)都必須是小寫。 十六進位制字串中不能包含多餘的前導零。如果要轉化的數為0,那麼以單個字元'0'來表示;對於其他情況,十六進位制字串中的第一

超長的轉換為八

之前在oj上做過,今天做藍橋杯基礎練習又遇到了這題 but沒有一遍AC 基礎練習 十六進位制轉八進位制 時間限制:1.0s 記憶體限制:512.0MB 提交此題 錦囊1 錦囊2 問題描述   給定n個十六進位制正整數,輸出它們對應的八進位制數。 輸入格式   輸入的第一行為一個正整數

java基礎。輸入一,轉化成十進位制

package lo; import java.util.Scanner; public class Test {     public static void main(String[] args){         //輸入一個十六進位制數字,顯示它所對應的十進位制數

數字轉換為(leetcode簡單篇四百零五題)

給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。對於負整數,我們通常使用 補碼運算 方法。 注意: 十六進位制中所有字母(a-f)都必須是小寫。 十六進位制字串中不能包含多餘的前導零。如果要轉化的數為0,那麼以單個字元’0’來表示;對於其他情況,十六進位制字串中

隨筆-數字(任意)轉換為

題目: 給定一個整數,編寫一個演算法將這個數轉換為十六進位制數。對於負整數,我們通常使用 補碼運算 方法。 注意: 十六進位制中所有字母(a-f)都必須是小寫。 十六進位制字串中不能包含多餘的前導零。如果要轉化的數為0,那麼以單個字元’0’來表示;對於其他情況,十六進位制字串