在交淡的时候,有些人喜欢重载一些旧的词语--给它们赋予新的意思,甚至创造出一些新词语,这体现了一定
的创造力。不要一味埋怨别人说的唐突,而应该努力根据事情的前后、话的前文来理解这些新的词语,并接受
它。
函数名重载能给我们带来一定的方便。
使用函数的缺省参数,有时也会给我们带来方便。但这样做是不是对用户程序员隐瞒了一些真相?因为他/她可
能会觉得很奇怪,“我明明没有传值进去,怎么那个值就起作用了?!”。除非这些参数是用户程序员很不想
理会的参数,比如很多win32 api函数有很多参数是用户不想理会的,那你隐藏使用默认的就好了;但如果那个
参数是某个文件的目录,这样也缺省的话就不太好了。
把缺省参数作为保留参数也是一个有效的做法,如一个函数原型这样声明: void SearchByInfo( const char*
par1, const int par2, const double par3, int = 0 ); 最后一个参数可以作为保留参数。
位向量的一个实现:
/************************************************************************/
/* 位向量 头文件
/* bs from thinking in C++
/************************************************************************/
#ifndef _BITVECTOR_H
#define _BITVECTOR_H
namespace _bs_classes_
{
class BitVector
{
public:
BitVector( );
BitVector( unsigned char * srcBytes, int nByteSize = 8 );
BitVector( char * pSrcBitString );
virtual ~BitVector( );
public:
// get bit number
int bits( );
// reset bit number
void bits( int nBitNum );
void set( int nBitPos );
void clear( int nBitPos );
int read( int nBitPos );
void print( const char * msg = "" );
private:
unsigned char * m_bits;
int m_nByteNum;
int m_nBitNum;
};
}
#endif // _BITVECTOR_H
/************************************************************************/
/* 位向量 实现文件
/* bs from thinking in C++
/************************************************************************/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <climits> // for CHAR_BIT
#include "BitVector.h"
using namespace _bs_classes_;
BitVector::BitVector( )
{
m_bits = 0;
m_nBitNum = 0;
m_nByteNum = 0;
}
BitVector::~BitVector( )
{
free( m_bits );
m_nBitNum = 0;
m_nByteNum = 0;
}
BitVector::BitVector(
unsigned char * srcBytes,
int nByteSize /* = 8 */
)
{
m_nByteNum = nByteSize;
m_nBitNum = m_nByteNum * CHAR_BIT;
m_bits = (unsigned char *)calloc( m_nByteNum, 1 );
assert( m_bits );
if ( srcBytes == 0 )
return;
const unsigned char highBit = (const unsigned char)(1 << CHAR_BIT-1);
for ( int nBytePos = 0; nBytePos < m_nByteNum; nBytePos ++ )
{
for ( int nBitPos = 0; nBitPos < CHAR_BIT; nBitPos ++ )
{
if ( srcBytes[nBytePos] & (highBit >> nBitPos) ) // 注意highBit的值并没
有改变
{
set( nBytePos * CHAR_BIT + nBitPos );
}
}
}
}
BitVector::BitVector(
char * pSrcBitString // 0101001..
)
{
assert( pSrcBitString );
if ( !pSrcBitString )
return;
m_nBitNum = strlen( pSrcBitString );
m_nByteNum = m_nBitNum / CHAR_BIT;
if ( m_nBitNum % CHAR_BIT )
m_nByteNum ++;
m_bits = (unsigned char *)calloc( m_nByteNum, 1 );
assert( m_bits );
for ( int nBitPos = 0; nBitPos < m_nBitNum; nBitPos ++ )
{
if ( pSrcBitString[nBitPos] == '1' )
{
set( nBitPos );
}
}
}
/*
* 对外接口
*/
void BitVector::set( int nBitPos )
{
assert( nBitPos >= 0 && nBitPos < m_nBitNum );
if ( nBitPos < 0 || nBitPos >= m_nBitNum )
return;
int nByte = nBitPos / CHAR_BIT;
int nOffset = nBitPos % CHAR_BIT;
unsigned char mask = (1 << nOffset); // 从右往左
m_bits[nByte] |= mask;
}
int BitVector::read( int nBitPos )
{
assert( nBitPos >= 0 && nBitPos < m_nBitNum );
int nByte = nBitPos / CHAR_BIT;
int nOffset = nBitPos % CHAR_BIT;
unsigned char mask = (1 << nOffset); // 从右往左
return m_bits[nByte] & mask;
}
void BitVector::clear( int nBitPos )
{
assert( nBitPos >= 0 && nBitPos < m_nBitNum );
if ( nBitPos < 0 || nBitPos >= m_nBitNum )
return;
int nByte = nBitPos / CHAR_BIT;
int nOffset = nBitPos % CHAR_BIT;
unsigned char mask = ~(1 << nOffset);
m_bits[nByte] &= mask;
}
int BitVector::bits( )
{
return m_nBitNum;
}
// 重新设置大小
void BitVector::bits( int nBitNum )
{
int nOldBitNum = m_nBitNum;
m_nBitNum = nBitNum;
m_nByteNum = m_nBitNum / CHAR_BIT;
if ( m_nBitNum % CHAR_BIT )
m_nByteNum ++;
void * pNewMem = realloc( m_bits, m_nByteNum );
assert( pNewMem );
m_bits = (unsigned char *)pNewMem;
for ( int nPos = nOldBitNum; nPos < m_nBitNum; nPos ++ )
{
clear( nPos ); // 新增的clear
}
}
void BitVector::print( const char * msg /* = "" */)
{
puts( msg );
for ( int nPos = 0; nPos < m_nBitNum; nPos ++ )
{
if ( read( nPos ) )
putchar( '1' );
else
putchar( '0' );
if ( (nPos + 1) % CHAR_BIT == 0 )
putchar( ' ' );
}
putchar( '/n' );
}
// 测试代码
#include <iostream>
using namespace std;
#include <cstdlib>
#include <cassert>
#include "BitVector.h"
using namespace _bs_classes_;
void testBitVector( )
{
BitVector bitVector1( "01000110001010010111101" );
bitVector1.print( "initialize to be: " );
cout << "bit number: " << bitVector1.bits( ) << endl;
bitVector1.set( 21 );
bitVector1.clear( 22 );
bitVector1.print( "after modified: " );
cout << "*******" << endl;
unsigned char buf[] = { 0x0f, 0xff, 0xad, 0x2a, 0x34 };
BitVector bitVector2( buf, sizeof buf / sizeof *buf );
bitVector2.print( "initialize to be: " );
cout << "bit number: " << bitVector2.bits( ) << endl;
bitVector2.set( 3 );
bitVector2.clear( 4 );
bitVector2.print( "after modified: " );
bitVector2.bits( bitVector2.bits() / 2 );
bitVector2.print( "after cut in half: " );
bitVector2.bits( bitVector2.bits() + 10 );
bitVector2.print( "after grown by 10: " );
cout << "********" << endl;
BitVector bitVector3;
bitVector3.bits( 64 );
bitVector3.print( "initialize to be: " );
}
以下是c++标准位向量bitset的简单使用例子:
// 包括头文件<bitset>
int main( )
{
//testBitVector();
bitset<64> bitVector;
cout << "size: " << bitVector.size( ) << endl;
cout << bitVector << endl;
bitVector.set( 1 ); // 从右往左
cout << bitVector << endl;
bitVector.reset( 1 );
cout << bitVector << endl;
bitVector.set( 10 );
cout << bitVector.at( 10 ) << endl;
cout << bitVector << endl;
return 1;
}