进制转化、自定义数据验证、虚函数验证
进制转化在实际编程是非常重要的,特别是网络数据传输(在进行大量数据传输时有时为了提高效率就要考虑对位操作了)。同时进制转化还可以进行数据验证,看看自定义数据类型对象是否如预料的一样存放有序,在今天的文章里要讲一下使用自己写的进制转化函数探究类数据和虚函数的实质。
首先,进制有二进制、八进制、十进制、十六进制。其表示的含义应当不用说了,下面就如何实现进行论述。(八进制转化不说了,不常用)
1,十进制到二进制转化
算法思想:使用移位的方法(提高效率)获取每一位数据。
void ToBinary(void *num, int binary[], int n = 1)
//使用void*指针可以实现任意数据的输入
//binary[]为传入的数组,存放转化好的数据,n为要转化的字节数
{
byte* number = (byte*)num;
int count = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < 8; j++)
{
if((*number & (1 << j)) != 0)
{
binary[count++] = 1;
}
else
binary[count++] = 0;
}
number++;
}
}
2,二进制到十六进制
算法思想:每四个为组合成一个十六进制位
void BinaryToHex(int binary[], char hex[], int n = 1)
//binary[]传入的二进制数组
//hex[]传入的十六进制数组,n为字节数,和上述相同
{
int sum = 0;
int count = 0;
for(int i = 0; i < n * 8; i++)
{
if(binary[i] == 1)
sum += 1 << (i % 4); //每四位组合成一个十六进制的位
if((i != 0) && ((i + 1) % 4 == 0))
{
if((sum < 10)&&(sum >= 0))
{
hex[count++] = '0' + sum;
sum = 0;
}
else
{
hex[count++] = 'A' + (sum - 10);
sum = 0;
}
}
}
}
3,十进制到十六进制
算法思想:先转化为二进制,再转化到十六进制
//打印任意数据的十六进制表示, n表示要显示字节使用sizeof
//先转化为二进制再转化为十六进制
void ToHex(void *num, char hex[], int n = 1)
{
byte* number = (byte*)num;
int* binary = new int[n * 8];
ToBinary(num, binary, n);
BinaryToHex(binary, hex, n);
delete[] binary;
}
4,将以上函数封装到类里面
见以下源码
//convert.h
#ifndef byte
#define byte unsigned char
#endif
#ifndef CONVERT_H
#define CONVERT_H
class convert
{
public:
//打印任意数据的二进制表示, n表示要显示的位数
//可以使用sizeof()来输入
//默认是1字节,一个字节一个字节的转化
static void ToBinary(void *num, int binary[], int n = 1)
{
byte* number = (byte*)num;
int count = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < 8; j++)
{
if((*number & (1 << j)) != 0)
{
binary[count++] = 1;
}
else
binary[count++] = 0;
}
number++;
}
}
//打印任意数据的十六进制表示, n表示要显示字节使用sizeof
//先转化为二进制再转化为十六进制
static void ToHex(void *num, char hex[], int n = 1)
{
byte* number = (byte*)num;
int* binary = new int[n * 8];
ToBinary(num, binary, n);
BinaryToHex(binary, hex, n);
delete[] binary;
}
//二进制到十六进制的转化,n为字节数
static void BinaryToHex(int binary[], char hex[], int n = 1)
{
int sum = 0;
int count = 0;
for(int i = 0; i < n * 8; i++)
{
if(binary[i] == 1)
sum += 1 << (i % 4); //每四位组合成一个十六进制的位
if((i != 0) && ((i + 1) % 4 == 0))
{
if((sum < 10)&&(sum >= 0))
{
hex[count++] = '0' + sum;
sum = 0;
}
else
{
hex[count++] = 'A' + (sum - 10);
sum = 0;
}
}
}
}
};
#endif
其次,进行验证(由于测试函数中有注释因此不再赘述了,直接给出源码)
// 进制转换.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "convert.h"
using namespace std;
union U
{
int i;
byte c;
};
class A
{
public:
int i;
int c;
void print()
{
cout << i << c;
}
};
class B
{
public:
int i;
int c;
virtual void print()
{
cout << "right";
}
};
//从当前指针获取它指向的下一个指针
void *getp(void* p)
{
return (void*)*(unsigned long*)p;
}
typedef void (*fun)(); //定一个函数指针
//取得该类虚函数
fun getFun(B* obj, unsigned long off)
{
void* vptr = getp(obj);
unsigned char *p = (unsigned char*)vptr;
p += sizeof(void*) * off;
return (fun)getp(p);
}
int main(int argc, char* argv[])
{
U u;
u.i = 256;
u.c = 15;
char* hex = new char[sizeof(u) * 2];
convert::ToHex(&u, hex, sizeof(u));
cout << "共用体数据测试:" << endl;
for(int i = sizeof(u) * 2 - 1; i >= 0; i--)
{
cout << hex[i];
}
cout << endl;
delete[] hex;
hex = NULL;
//共用体所有的数据成员占用的是共同的存储空间
int n = -1;
int *p = new int[sizeof(n) * 8];
convert::ToBinary(&n, p, sizeof(n));
cout << "整型数据测试:" << endl;
for(i = sizeof(n) * 8 - 1; i >= 0; i--)
{
cout << p[i];
}
cout << endl;
delete p;
p = NULL;
//有符号整型最高位是符号位
A a;
a.i = 8;
a.c = 1;
p = new int[sizeof(a) * 8];
convert::ToBinary(&a, p, sizeof(a));
cout << "类数据测试:" << endl;
for(i = sizeof(a) * 8 - 1; i >= 0; i--)
{
cout << p[i];
}
cout << endl;
delete p;
p = NULL;
//可以发现类的私有成员变量占用了空间,而类的成员函数没有占用空间
B b;
b.i = 8;
b.c = 1;
p = new int[sizeof(b) * 8];
convert::ToBinary(&b, p, sizeof(b));
cout << "含有虚函数类数据测试:" << endl;
for(i = sizeof(b) * 8 - 1; i >= 0; i--)
{
cout << p[i];
}
cout << endl;
delete p;
p = NULL;
//可以发现类的私有成员变量占用了空间,而类的虚成员函数也占用空间4字节
//下面使用函数指针将类成员函数打印出来
fun f = getFun(&b, 0);
(*f)(); //注意此时不能访问成员变量
cout << endl;
return 0;
}