C/C++实现int、long、double以及含有字符串的结构体与字节数组之间的相互转换

一、对象地址与排列方式

我们首先需要明白,对于跨越多字节的程序对象,我们必须建立两个规则:

  • 1)对象的地址是什么?在几乎所有的机器上,多字节对象都被存储为连续的字节序列,如int类型对象为四个字节序列,对象的地址为所使用的字节中的最小的地址。
  • 2)如何排列这些字节?(大端法、小端法)
    大端法:在内存中按照从最有效字节到最有效字节的顺序存储对象,最有效字节在前面
    小端法:在内存中按照从最有效字节到最有效字节的顺序存储对象,最有效字节在前面
    在这里插入图片描述

二、int、long、double类型与字节数组的转换

int类型的变量转成字节数组,下面这种转换用于在同一机器不同语言(Java与C++)之间交换数据时保持统一,所以不用考虑大小端,只需要将变量的最小地址和字节数组的首地址对应,依次将所有字节中的值放进去即可。同理longdouble占用8个字节。

char* Int2Bytes(int32_t value) {
    
    
	char *bytes = reinterpret_cast<char*>(malloc(4 * sizeof(char)));
	char *minAdd = reinterpret_cast<char*>(&value);//取到最小地址
	//变量value占用四个字节,所以只需要分别将四个字节依次放入字节数组即可
	for (int i = 0; i < 4; i++) {
    
    
		bytes[i] = *minAdd++;
	}
	return bytes;
}

int Bytes2Int(char *bytes) {
    
    
	int value = *reinterpret_cast<int32_t*>(bytes);
	return value;
}

char* Long2Bytes(int64_t value) {
    
    
	char *bytes = reinterpret_cast<char*>(malloc(8 * sizeof(char)));
	char *minAdd = reinterpret_cast<char*>(&value);
	for (int i = 0; i < 8; i++) {
    
    
		bytes[i] = minAdd[i];
	}
	return bytes;
}

long Bytes2Long(char *bytes) {
    
    
	long value = *reinterpret_cast<int64_t*>(bytes);
	return value;
}

char* Double2Bytes(double value) {
    
    
	char *bytes = reinterpret_cast<char*>(malloc(8 * sizeof(char)));
	char *minAdd = reinterpret_cast<char*>(&value);
	for (int i = 0; i < 8; i++) {
    
    
		bytes[i] = minAdd[i];
	}
	return bytes;
}

double Bytes2Dobule(char *bytes) {
    
    
	double value = *(reinterpret_cast<double*>(bytes));
	return value;
}

三、含有字符串的结构体与字节数组的转换

typedef struct {
    
    
	int errCode;
	char *errMassage;
	char *errLocal;
} ExceptionVal;

char* ExceptionVal2Bytes(int code, const char *message, const char *local,
		int &len) {
    
    
	int index = 0;
	int messageLen = 0;
	int localLen = 0;
	int bytesLen = 0;

	while (message[messageLen] != '\0')
		messageLen++;
	while (local[localLen] != '\0')
		localLen++;
	len = bytesLen = 4 + 4 + 4 + messageLen + localLen;

	char *bytes = reinterpret_cast<char*>(malloc(bytesLen * sizeof(char)));
	char *messageLenBytes = Int2Bytes(messageLen);
	char *localLenBytes = Int2Bytes(localLen);
	char *codeBytes = Int2Bytes(code);

	for (int i = 0; i < 4; i++)
		bytes[index++] = messageLenBytes[i];
	for (int i = 0; i < 4; i++)
		bytes[index++] = localLenBytes[i];
	for (int i = 0; i < 4; i++)
		bytes[index++] = codeBytes[i];
	for (int i = 0; i < messageLen; i++)
		bytes[index++] = message[i];
	for (int i = 0; i < localLen; i++)
		bytes[index++] = local[i];

	return bytes;
}

ExceptionVal* Bytes2ExceptionVal(char *bytes) {
    
    
	ExceptionVal *excepVal = reinterpret_cast<ExceptionVal*>(malloc(
			sizeof(ExceptionVal)));
	int index = 0;
	char *messageLenBytes = reinterpret_cast<char*>(malloc(4 * sizeof(char)));
	char *localLenBytes = reinterpret_cast<char*>(malloc(4 * sizeof(char)));
	char *codeBytes = reinterpret_cast<char*>(malloc(4 * sizeof(char)));

	for (int i = 0; i < 4; i++)
		messageLenBytes[i] = bytes[index++];
	for (int i = 0; i < 4; i++)
		localLenBytes[i] = bytes[index++];
	for (int i = 0; i < 4; i++)
		codeBytes[i] = bytes[index++];

	int messageLen = Bytes2Int(messageLenBytes);
	int localLen = Bytes2Int(localLenBytes);
	char *errMessage = reinterpret_cast<char*>(malloc(
			(messageLen + 1) * sizeof(char)));
	char *errLocal = reinterpret_cast<char*>(malloc(
			(localLen + 1) * sizeof(char)));

	excepVal->errCode = Bytes2Int(codeBytes);

	for (int i = 0; i < messageLen; i++)
		errMessage[i] = bytes[index++];
	errMessage[messageLen] = '\0';
	excepVal->errMassage = errMessage;

	for (int i = 0; i < localLen; i++)
		errLocal[i] = bytes[index++];
	errLocal[localLen] = '\0';
	excepVal->errLocal = errLocal;

	return excepVal;
}

四、测试及其结果

#include <iostream>

/**
 * 假装这里有前面出现的所有方法
 */
 
void printBytes(char *bytes, int size) {
    
    
	printf("\nbyteArry:");
	for (int i = 0; i < size; i++) {
    
    
		printf("%d", bytes[i]);
		if (i < size - 1)
			printf(",");
		else
			printf("\n");
	}
}

int main() {
    
    
	// int 类型互转
	int32_t intVal = 154654600;
	char *bytes1 = Int2Bytes(intVal);
	printBytes(bytes1, 4);
	std::cout << Bytes2Int(bytes1) << std::endl;

	// long 类型互转
	int64_t longVal = 1254546132;
	char *bytes2 = Long2Bytes(longVal);
	printBytes(bytes2, 8);
	std::cout << Bytes2Long(bytes2) << std::endl;

	// double 类型互转
	double doubleVal = 3.1415;
	char *bytes3 = Double2Bytes(doubleVal);
	printBytes(bytes3, 8);
	std::cout << Bytes2Dobule(bytes3) << std::endl;

	// 带有字符串的struct 类型转换
	int errCode = 1245216;
	const char *errMessage = "too many local cursor";
	const char *errLocal = "At FUN2_I_DATE_S_1 Line 10, Column 0";
	int len = 0;
	char *bytes4 = ExceptionVal2Bytes(errCode, errMessage, errLocal, len);
	printBytes(bytes4, len);
	ExceptionVal *excepVal = Bytes2ExceptionVal(bytes4);
	std::cout << excepVal->errCode << std::endl;
	std::cout << excepVal->errMassage << std::endl;
	std::cout << excepVal->errLocal << std::endl;
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42570601/article/details/115494431