面向对象程序设计第一次实验课——位运算封装
来源:互联网 发布:sai软件怎么下载 编辑:程序博客网 时间:2024/06/06 14:04
题目的大意是用一个类封装位运算,并通过位运算实现四则运算。我一下子就想起了bitset,但是bitset并不支持四则运算。后来想想也许叫大整数类比较合适吧。
当然还是有很多问题的,有些问题是写完了才发现的,当时发着高烧,一边写一边debug,好不容易赶到deadline前,交过之后也没有改的动力了……
首先是该用友元实现的二元关系的运算符全写在类内了,写之前应该看看书的。其次是没有实现下标运算符的重载,这个要用到设计模式中的代理模式,同样是没来得及写,这里有篇blog里面实现了:
http://blog.csdn.net/fastsort/article/details/8922923
一些其他问题写在了实验报告中。
bit.h
#pragma once#include <string>#include <cstring>#include <cmath>#define BLOCK (len_ / (8 * sizeof(size_t)) + (len_ % (sizeof(size_t) * 8)? 1: 0))#define BLOCKBIT (8 * sizeof(size_t)) using namespace std;template <size_t len_> //len_ is the number of bit(s) class myBitset { friend ostream& operator<< (ostream &out, const myBitset<len_>& bs) { // stored reversely, so output reversely for (size_t i = 0; i < len_; i ++) { if (bs.isTrue(len_ - i - 1)) out << "1"; else out << "0";// printf("%d ",i); } return out; } public: myBitset() : block_(BLOCK) { num_ = new size_t[block_]; memset(num_, 0, block_ * sizeof(size_t));// printf("%d %d %d\n", block_, sizeof(size_t), block_ * sizeof(size_t));// for (int i = 0; i < block_; i ++) num_[i] = 0;// cout << *this << endl; } myBitset(const myBitset& bs);//invert signed number to myBitset, and avoid ambiguous calling for overloaded functions myBitset(signed int num); myBitset(unsigned int num); myBitset(signed long); myBitset(unsigned long);// myBitset(signed long long);// myBitset(unsigned long long); myBitset(signed __int64 num); myBitset(unsigned __int64 num); myBitset(const string& s); ~myBitset(); myBitset& operator= (const myBitset& bs); myBitset operator& (const myBitset& bs) const; myBitset operator| (const myBitset& bs) const; myBitset operator~ (void) const; myBitset operator^ (const myBitset& bs) const; // BOTH TWO BELOW ARE LOGICAL SHIFT! BE CAREFUL ! myBitset operator<< (size_t shift) const; myBitset operator>> (size_t shift) const; myBitset& operator&= (const myBitset& bs); myBitset& operator|= (const myBitset& bs); myBitset& operator^= (const myBitset& bs); myBitset& operator<<= (size_t shift); myBitset& operator>>= (size_t shift); myBitset& operator++ (void); myBitset& operator-- (void); myBitset operator++ (int dummy); myBitset operator-- (int dummy); // in operator+= we need local variables of myBitset, so argument is not reference myBitset& operator+= (myBitset bs); myBitset& operator-= (const myBitset& bs); myBitset operator+ (const myBitset& bs) const; myBitset operator- (const myBitset& bs) const; myBitset operator+ (void) const; myBitset operator- (void) const; myBitset operator* (const myBitset& bs) const; myBitset operator/ (const myBitset& bs) const;// myBitset operator% (const myBitset& bs) const; myBitset& operator*= (myBitset bs); myBitset& operator/= (myBitset bs); bool operator> (const myBitset& bs) const; bool operator>= (const myBitset& bs) const; bool operator< (const myBitset& bs) const; bool operator<= (const myBitset& bs) const; bool operator== (const myBitset& bs) const; bool operator!= (const myBitset& bs) const; explicit operator bool(void) const; void flip();// flip all bits void set(size_t index); void reset(size_t index); bool isTrue(size_t index) const; size_t getBlock(void) { return block_;} size_t getLen(void) { return len_;} private: size_t* num_; //pointer to where the bits stored const size_t block_; //the size of the array };template <size_t len_> myBitset<len_>::myBitset(const myBitset<len_>& bs) : block_(bs.block_){ num_ = new size_t[block_]; for (size_t i = 0; i < bs.block_; i ++) num_[i] = bs.num_[i];}// lower bit is stored in the smaller indextemplate <size_t len_> myBitset<len_>::myBitset(unsigned __int64 num) : myBitset(){ size_t p = 0;// printf("%llu\n",num); while (num && p < len_) { if (num & 1) { set(p);// printf("%d\n",p); } ++ p; num >>= 1; } // size_t is an unsigned type !!}//template <size_t len_> myBitset<len_>::myBitset(unsigned long long num) : // myBitset(unsigned __int64(num)) {}template <size_t len_> myBitset<len_>::myBitset(unsigned long num) : myBitset(static_cast<unsigned __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(unsigned int num) : myBitset(static_cast<unsigned __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed __int64 num) : myBitset(static_cast<unsigned __int64>(abs(num))){ if (num < 0) { flip(); ++ (*this); }}//template <size_t len_> myBitset<len_>::myBitset(signed long long num) : // myBitset(signed __int64(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed long num) : myBitset(static_cast<signed __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(signed int num) : myBitset(static_cast<signed __int64>(num)) {}template <size_t len_> myBitset<len_>::myBitset(const string& s) : myBitset(){ for (size_t i = 0; i < s.size(); i ++) { if (s[i] != '0') { set(s.size() - i - 1); } }}template <size_t len_> myBitset<len_>::~myBitset(){ delete []num_;}template <size_t len_> inline void myBitset<len_>::set(size_t index){ // 1不加强制类型转换为什么会出现循环左移…… num_[index / BLOCKBIT] |= (size_t(1) << (index % BLOCKBIT));// printf("%d %d %d\n",index, index / BLOCKBIT, index % BLOCKBIT); return ;}template <size_t len_> inline void myBitset<len_>::reset(size_t index){ num_[index / BLOCKBIT] &= ~(size_t(1) << (index % BLOCKBIT)); return ;}template <size_t len_> inline bool myBitset<len_>::isTrue(size_t index) const{// if (num_[index / BLOCKBIT] & (size_t(1) << (index % BLOCKBIT))) printf(" %d %d %d\n",index, index / BLOCKBIT,index %BLOCKBIT);// printf("%llu\n",1 << (index % BLOCKBIT)); return num_[index / BLOCKBIT] & (size_t(1) << (index % BLOCKBIT));}template <size_t len_> inline void myBitset<len_>::flip(void){ for (size_t i = 0; i < block_; i ++) { num_[i] = ~num_[i]; } return ;}template <size_t len_> myBitset<len_>& myBitset<len_>::operator= (const myBitset& bs){ if (this != &bs) { for (size_t i = 0; i < block_; i ++) num_[i] = bs.num_[i]; }}template <size_t len_> myBitset<len_> myBitset<len_>::operator&(const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs &= bs; return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator|(const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs |= bs; return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator~(void) const{ myBitset<len_> tbs(*this); tbs.flip(); return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator^(const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs ^= bs; return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator<<(size_t shift) const{ myBitset<len_> tbs(*this); tbs <<= shift; return tbs;}template <size_t len_> myBitset<len_> myBitset<len_>::operator>>(size_t shift) const{ myBitset<len_> tbs(*this); tbs >>= shift; return tbs;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator&= (const myBitset& bs){ for (size_t i = 0; i < block_; i ++) { num_[i] &= bs.num_[i]; } return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator|= (const myBitset& bs){ for (size_t i = 0; i < block_; i ++) { num_[i] |= bs.num_[i]; } return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator^= (const myBitset& bs){ for (size_t i = 0; i < block_; i ++) { num_[i] ^= bs.num_[i]; } return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator<<= (size_t shift){ if (shift == 0) return *this; if (shift >= len_) { memset(num_, 0, block_ * sizeof(size_t)); return *this; } size_t blockShift = shift / BLOCKBIT; // the shift of how many units of array size_t innerShift = shift % BLOCKBIT; // the shift in the unit of array for (size_t i = 0; i < block_; i ++) { size_t opid = block_ - 1 - i; if (opid < blockShift) { num_[opid] = 0; } else { if (opid - blockShift > 0) num_[opid]=(num_[opid-blockShift]<<innerShift)|(num_[opid-blockShift-1]>>(BLOCKBIT-innerShift)); else num_[opid] = num_[opid - blockShift] << innerShift; } } return *this;}template<size_t len_> myBitset<len_>& myBitset<len_>::operator>>= (size_t shift){ // printf("%llu\n",num_[0]); if (shift == 0) return *this; if (shift >= len_) { memset(num_, 0, block_ * sizeof(size_t)); return *this; } size_t blockShift = shift / BLOCKBIT; // the shift of how many units of array size_t innerShift = shift % BLOCKBIT; // the shift in the unit of array for (size_t i = 0; i < block_; i ++) { if (i > block_ - 1 - blockShift) { num_[i] = 0; } else { if (i + blockShift + 1 < block_) num_[i]=(num_[i+blockShift]>>innerShift)|(num_[i+blockShift+1]<<(BLOCKBIT-innerShift)); else num_[i] = num_[i + blockShift] >> innerShift; } }// printf("%llu\n",tbs.num_[0]); return *this;}template <size_t len_> inline myBitset<len_>& myBitset<len_>::operator++ (void){ (*this) += 1; return *this;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator++ (int dummy){ myBitset<len_> tbs = (*this); ++ (*this); return tbs;}template <size_t len_> inline myBitset<len_>& myBitset<len_>::operator-- (void){ (*this) -= 1; return *this;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator-- (int dummy){ myBitset<len_> tbs = (*this); -- (*this); return tbs;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator+ (const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs += bs; return tbs;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator- (const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs += -bs; return tbs;}template <size_t len_> inline myBitset<len_>& myBitset<len_>::operator-= (const myBitset& bs){ *this += -bs; return *this;}template <size_t len_> inline myBitset<len_>& myBitset<len_>::operator+= (myBitset bs){ myBitset<len_> tbs; while ((bs)) { tbs = (*this) ^ bs; bs = (*this & bs) << 1; *this = tbs; } return *this;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator+ (void) const{ return *this;}template <size_t len_> inline myBitset<len_> myBitset<len_>::operator- (void) const{ myBitset<len_> tbs(*this); return ~(tbs) + 1;}template<size_t len_> myBitset<len_>::operator bool(void) const{ for (size_t i = 0; i < len_ ; i ++) { if (isTrue(i)) return true; } return false;}template <size_t len_> myBitset<len_>& myBitset<len_>::operator*= (myBitset bs){ if (!bs || !*this) { *this = 0; return *this; } int flag = 0; myBitset<len_> tbs(*this); *this = 0; if (isTrue(len_ - 1)) { flag = ~flag; tbs = -tbs; } if (bs.isTrue(len_ - 1)) { flag = ~flag; bs = -bs; } while (bs) { if (bs & 1) *this += tbs; tbs <<= 1; bs >>= 1; } if (flag) { *this = -(*this); } return *this;}template <size_t len_> myBitset<len_> myBitset<len_>::operator* (const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs *= bs; return tbs;}template <size_t len_> myBitset<len_>& myBitset<len_>::operator/= (myBitset bs){// cout << *this << " " << bs << endl; if (bs) { int flag = 0; myBitset<len_> tbs(*this); *this = 0; if (tbs.isTrue(len_ - 1)) { flag = ~flag; tbs = -tbs; } if (bs.isTrue(len_ - 1)) { flag = ~flag; bs = -bs; }// cout << tbs << " " << bs << endl; size_t highbit = 0; for (size_t i = len_ - 2; i > 0; i --) { if (tbs.isTrue(i)) { highbit = i; break; } } for (size_t i = 0; i <= highbit; i ++) { size_t op = highbit - i; // avoid overflow!!! if ((tbs >> op) >= bs) { tbs -= (bs << op); *this += (myBitset<len_>(1) << op); }// cout << op << " " << tbs << " " << bs << " " << *this << endl; } if (flag) { *this = -(*this); } return *this; } else { cout << "divisor cannot be 0 !" << endl; return *this; }}template <size_t len_> myBitset<len_> myBitset<len_>::operator/ (const myBitset& bs) const{ myBitset<len_> tbs(*this); tbs /= bs; return tbs;}template <size_t len_> bool myBitset<len_>::operator>= (const myBitset& bs) const{ return (*this > bs || *this == bs);}template <size_t len_> bool myBitset<len_>::operator> (const myBitset& bs) const{ if (!isTrue(len_ - 1) && isTrue(len_ - 1)) { return true; } if (isTrue(len_ - 1) && !isTrue(len_ - 1)) { return false; } for (size_t i = 0; i < block_; i ++) { size_t op = block_ - i - 1; if (num_[op] > bs.num_[op]) { return true; } if (num_[op] < bs.num_[op]) { return false; } } return false;}template <size_t len_> bool myBitset<len_>::operator== (const myBitset& bs) const{ if (*this ^ bs) { return false; } else { return true; }}template <size_t len_> inline bool myBitset<len_>::operator< (const myBitset& bs) const{ return !(*this >= bs);}template <size_t len_> inline bool myBitset<len_>::operator<= (const myBitset& bs) const{ return !(*this > bs);}template <size_t len_> inline bool myBitset<len_>::operator!= (const myBitset& bs) const{ return !(*this == bs);}
main.cpp
里面主要是测试
#include <iostream>#include <cmath>#include "bit.h"#include <bitset>using namespace std;int main(int argc, char** argv) { cout << (-11111 >> 30) << endl; cout << size_t(-1) << endl; cout << "test for set, reset and flip" << endl; myBitset<32> bt; bt.set(0); cout << bt << endl; bt.reset(0); cout << bt << endl; bt.set(31); cout << bt << endl; bt.flip(); cout << bt << endl; cout << endl << "test for constructor" << endl; string s = "100010"; myBitset<32> bt1; cout << bt1 << endl; myBitset<33> bt2(s); cout << bt2 << endl; myBitset<33> bt31(64); cout << bt31 << endl; myBitset<65> bt32(static_cast<unsigned long long>((size_t(1) << 63) + ((size_t(1) << 63) - 1))); cout << bt32 << endl; myBitset<33> bt4(bt31); cout << bt4 << endl; cout << endl << "test for <<, >> and =" << endl; myBitset<100> bt5(size_t(pow(2,31))+15); cout << bt5 << endl; cout << (bt5 << 4) << endl; cout << (bt5 >> 4) << endl; cout << (size_t(1) << 33) << endl; myBitset<100> bt6("100000011111111111000010101"); cout << bt6 << endl; bt6 = bt5; cout << bt6 << endl; myBitset<129> bt7 = string("10110011101111011111010101"); cout << bt7 << endl; cout << (bt7 >> 7) << endl; cout << (bt7 << 7) << endl; cout << (bt7 << 65) << endl; cout << (bt7 >> 65) << endl; cout << endl << "test for &, |, ~ and ^" << endl; myBitset<70> bt8("1011011101111011111011111101111111011111111011111111101111111111011110"); cout << bt8 << endl; myBitset<70> bt9(~bt8); cout << bt9 << endl; cout << (bt8 | bt9) << endl; cout << (bt8 & bt9) << endl; cout << (bt8 ^ bt9) << endl; cout << (bt8 ^ bt9 ^ bt8) << endl; cout << endl << "test for &=, |= and ^=" << endl; cout << bt8 << endl; bt8 &= bt9; cout << bt8 << endl; bt8 |= bt9; cout << bt8 << endl; bt8 ^= ~bt9 ^ 1; cout << bt8 << endl; cout << endl << "test for <<= and >>=" << endl; myBitset<70> bt10("1011011101111011111011111101111111011111111011111111101111111111011111"); cout << bt10 << endl; cout << (bt10 << 65) << endl; bt10 <<= 65; cout << bt10 << endl; bt10 = string("1011011101111011111011111101111111011111111011111111101111111111011111"); cout << (bt10 >> 65) << endl; bt10 >>= 65; cout << bt10 << endl; cout << endl << "test for + and -" << endl; bt9 = string("1011011101111011111011111101111111011111111011111111101111111111011111"); bt10 = ~bt9; cout << bt9 << endl; cout << bt10 << endl; cout << (-bt9) << endl; cout << (-bt10) << endl; cout << (bt9 + bt10) << endl; cout << (bt9 - (bt10>>3)) << endl; bt9 = -1; bt10 = 64; cout << (bt9 + bt10) << endl; cout << (bt9 - bt10) << endl; cout << endl << "test for ++, -- , += and -=" << endl; bt9 = string("1011011101111011111011111101111111011111111011111111101111111111011111"); bt10 = ~bt9; cout << (bt9 ++) << endl; cout << bt9 << endl; cout << (bt10 --) << endl; cout << bt10 << endl; cout << (++ bt9) << endl; cout << bt9 << endl; cout << (-- bt10) << endl; cout << bt10 << endl; bt10 += 1; cout << bt10 << endl; bt10 -= 3; cout << bt10 << endl; cout << endl << "test for *, *=, /, /=" << endl; bt9 = -13; bt10 = 3; bt9 *= bt10; cout << bt9 << endl; cout << (bt9 * bt10) << endl; bt9 *= -3; bt10 *= 100; cout << bt9 << endl; cout << bt10 << endl; cout << endl << "test for /, /=" << endl; bt9 = 10; bt10 = 3; cout << (bt9 >= bt10) << endl; cout << (bt9 >> 3) << endl; cout << ((bt9 >> 3) >= bt10) << endl; cout << (bt9 << 0) << endl; cout << (myBitset<70>(1) << 0) << endl; bt9 /= bt10; cout << bt9 << endl; bt9 = -10; bt10 = 3; cout << (bt9 / bt10) << endl; cout << (bt10 / bt9) << endl; return 0;}
附:实验报告
第一次实验报告
一、 题目分析
位运算的封装:
第一次看到这个题目,我想到了stl中的bitset,bitset实现了对bit类型数组的封装,同时支持六种位运算,我的目的就是实现类似于bitset的类模版。
六种位运算& | ~ ^ << >> 支持基础数据类型,但是基础数据类型的大小是固定的,不能支持bit数高于8 * sizeof(size_t)(最大一般是64bit)的要求,而且不能支持任意位数的bit类型数组,这样显然不能满足我们的要求。
因此,我决定使用size_t类型的数组,通过基础类型的位运算实现对每一个size_t内的位的操作,从而实现对抽象的“位类型”的操作。
除了最基础的构造函数、析构函数、拷贝运算符,实现了六种位运算,还实现了布尔类型的类型转换,逻辑运算,和+-*/四则运算和自增自减运算以及流插入操作符重载。
100!的计算:
首先想到的是高精度乘法,通过数组存储大数的每一位,模拟竖式乘法,从而得解。
二、 流程分析(感觉太复杂了画图有些困难,所以通过文字描述)
这里介绍位运算封装的流程,大数阶乘比较简单。
1. 构造函数:
共9个,最基础的是默认构造函数,在其中完成相关变量初始化和内存空间的申请。
之后是拷贝构造函数,myBitset(unsigned __int64 num); myBitset(const string& s); 它们首先使用默认构造函数进行委托构造,之后再实现自己特定的构造。
在之后是以其他各种无符号或有符号整数做参数的构造函数,它们使用myBitset(unsigned __int64 num);进行委托构造,从而完成功能。
2.基础功能的实现
共4个,分别是
void flip();
void set(size_t index);
void reset(size_t index);
bool isTrue(size_t index) const;
flip实现按位取反,set实现对下标是index的置1,reset是实现对下标是index的置0,isTrue判断下标为index的位是否是1,接下来的许多函数都是需要直接或者间接调用这些函数的。
2. 位运算运算符以及=的重载
myBitset& operator= (const myBitset& bs);
myBitset operator& (const myBitset& bs) const;
myBitset operator| (const myBitset& bs) const;
myBitset operator~ (void) const;
myBitset operator^ (const myBitset& bs) const;
myBitset operator<< (size_t shift) const;
myBitset operator>> (size_t shift) const;
myBitset& operator&= (const myBitset& bs);
myBitset& operator|= (const myBitset& bs);
myBitset& operator^= (const myBitset& bs);
myBitset& operator<<= (size_t shift);
myBitset& operator>>= (size_t shift);
首先实现的是&= |= 等函数,之后& |等运算符通过调用&= |= 等实现功能。
3. 四则运算与自增自减
myBitset& operator++ (void);
myBitset& operator– (void);
myBitset operator++ (int dummy);
myBitset operator– (int dummy);
myBitset& operator+= (myBitset bs);
myBitset& operator-= (const myBitset& bs);
myBitset operator+ (const myBitset& bs) const;
myBitset operator- (const myBitset& bs) const;
myBitset operator+ (void) const;
myBitset operator- (void) const;
myBitset operator* (const myBitset& bs) const; myBitset operator/ (const myBitset& bs) const; myBitset& operator*= (myBitset bs); myBitset& operator/= (myBitset bs);
同样,首先实现的是+= -=等,对应的双目运算符则调用前者,单目-调用~运算符。
前置自增自减调用+= -=,而后置自增自减调用前置自增自减。
4. 逻辑运算符与bool类型转换
bool operator> (const myBitset& bs) const;
bool operator>= (const myBitset& bs) const;
bool operator< (const myBitset& bs) const;
bool operator<= (const myBitset& bs) const;
bool operator== (const myBitset& bs) const;
bool operator!= (const myBitset& bs) const;
explicit operator bool(void) const;
bool类型转换函数调用isTrue函数。
实现的是>和==,其他逻辑运算符直接或间接调用这两个函数。
三、程序难点以及遇到的主要bug
1.构造函数
为了支持四则运算,必须提供参数无符号整型和有符号整型的构造函数,开始我只定义了unsigned __int64和 signed __int64为参数的构造函数,然而这时就会遇到二义调用的问题。
为了避免二义调用,我为常见的整型类型分别定义了构造函数。
2.移位运算
因为存储位的是数组,故实现移位操作时会遇到困难,通过寻找规律可以解决这一问题。
此外还遇到了如下问题。
一开始我并没有对1进行强制类型转换,转换成myBitset类型,按道理,1移位超过int位长时,这样会使1移位后的结果变成0(逻辑移位),但是,这里实际上竟然是循环移位。
而单单对1进行左移位,得到的结果是逻辑移位的结果。
目前还是没有弄明白是为什么。
因为首先实现的是<<=和>>= ,<< >>是通过调用<<= >>= 实现的,移位的时候可能会出现运算结果覆盖未进行运算数据的情况,所以要注意运算的顺序,>>要先从低位开始算,<<要先从高位开始算。
还遇到了移位0时出现的错误,需要特判shift为0时的情况。(除法调用移位操作时发现)
3.bool类型转换
一开始并没有把operator bool 声明为explicit,于是出现了双目运算符调用时的二义调用(左操作数为myBitset对象而右操作数为基础数据类型时),因为myBitset可以隐式的转换为bool类型,c++中bool类型实质上就是int类型。
在查资料之前,我尝试了在声明中加入了explicit关键字,尽管在我的印象中它只能用在构造函数的声明中,但是问题的确解决了,后来查资料发现,在c++11标准中,允许在类型转换运算符前加入explicit的声明,而对bool则更加特殊,在条件表达式中它允许隐式转换而在其他情况中只允许显式使用。
5. 不小心就会发生的间接递归
由于一些运算符要通过调用其他运算符实现,所以在头脑不清晰的情况下极易发生
递归,而且这类错误比较难发现,程序中出现的最长间接递归链甚至可达10个以上的函数。
6. 乘法与除法
在设计乘法的算法时我借鉴了快速幂算法的思想,只不过当第二个乘数为奇数时ans变量做的运算由乘变成了加,只要调用加法就可以实现乘法了。
除法就是乘法的逆运算。
7. size_t类型
size_t类型是一种无符号整数类型,具体类型依赖于环境,但它是非负的,用size_t类型做循环变量时,由于它不可能小于0,于是下面的语句会出现死循环。
For (size_t I = len_ - 1; I >= 0; I ++)
故程序中所有循环尽量写成正序的,需要反向的顺序时,通过循环变量计算出实际运算的下标。
四、 优点与缺点
封装位运算操作符
优点:
a) 实现了任意长度的位类型
b) 满足了所有的要求
c) 尽量使用已定义的方法去定义其他方法
d) 对于多个方法(已实现的或是以后可能实现的)会使用的相同方法,将该方法定义为一个函数
e) 实现了四则运算,自增自减,重载了流插入操作符。
缺点:
a) 最重大的失误:没有将二元运算符用非成员函数实现。(3 + myBitset<10>(1)是非法的)
b) 没有实现[]操作符。(代理模式)
c) 没有用myBitset类实现阶乘(主要是没有转换成整型的方法)
d) 没有定义将myBitset转换为整型的方法(大数进制转换)
e) 部分方法效率不高
- 面向对象程序设计第一次实验课——位运算封装
- 《C++面向对象程序设计》第一次实验
- 面向对象程序设计第三次实验课——Wuxing
- 面向对象第一次实验
- (转)JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(上)——封装[转]
- JavaScript 面向对象程序设计(上)——封装[转]
- JavaScript 面向对象程序设计(上)——封装
- JavaScript 面向对象程序设计(上)——封装[转]
- 5、理解面向对象程序设计——封装
- JavaScript 面向对象程序设计(上)——封装
- javascript面向对象程序设计——封装(by vczero)
- 5、理解面向对象程序设计——封装
- 面向对象程序设计第二次实验课——mystring类实现
- 面向对象程序设计第四次实验课——socket初试
- 面向对象程序设计第五次实验课——深拷贝
- 1
- 如何找出数组中重复次数的元素
- <UE4> 分析 UObjecBaseUtility
- 2
- python开发-Django框架使用
- 面向对象程序设计第一次实验课——位运算封装
- 深入浅出 Java 8 Lambda 表达式
- 数位DP模板
- Java实现快速排序
- 利用AnimationFrame 实现帧检测
- opencv批量调整图像大小
- html5 简单实例源代码
- github上如何删除一个项目(仓库)
- <大话设计模式>笔记