结构体和字符流的相互转换

参考:https://blog.csdn.net/qq_31094099/article/details/80790346

https://www.cnblogs.com/qicosmos/p/3601737.html

https://bbs.csdn.net/topics/390382122?page=1

https://blog.csdn.net/qq_29757283/article/details/83503581

工作中遇到了一个问题,在针对postgres源码和KPU对接的程序编写时,发现kpu的kernel函数的参数只能添加基础数据类型,我们无法将源码中的结构体发给kernel函数,所以我们要将结构体转换成int或者char等基础数据类型的数组来处理。

Demo程序

// C语言中结构体与字符数组之间的相互转换.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

typedef struct Score
{
	int math;
	int chinese;
	int english;
	//int physics;
	//int chemistry;
	//int biology;
	/*
	Score(int m, int c, int e) :math(m), chinese(c), english(e)
	{

	}
	void print()
	{
		printf("math:%d,chinese:%d,english:%d\n", math, chinese, english);
	}
	*/
}Score;

/*
#pragma pack(push)//保存对齐状态 
#pragma pack(1)
typedef struct strcChange
{
	unsigned char A;
	unsigned int B;
	unsigned double C;
	const char *D;
}STRU_CHANGE;
#pragma pack(pop)
*/

//如果在未加字节对齐的情况下,那么需要字节对齐,
//那么直接将结构体取地址后复制到另一个数组中,实际上所需占用的内存大小是8个byte。

typedef struct strcChange
{
	Score sco;
	unsigned char A;
	unsigned int B;
	float C;
	const char *D;
}STRU_CHANGE;

int main()
{
	STRU_CHANGE obj1;
	STRU_CHANGE *ptr;
	obj1.A = 'a';
	obj1.B = 5;
	obj1.C = 12.5;
	obj1.D = "hello";
	
	
	char *buf=new char[sizeof(STRU_CHANGE)];
	std::cout << sizeof(Score) << std::endl;
	std::cout<< sizeof(STRU_CHANGE) <<std::endl;
	printf("转换前数据结构内容:A=%c,B=%d,C=%f,D=%s\n",obj1.A,obj1.B,obj1.C, obj1.D);
	memcpy(buf,&obj1,sizeof(obj1));
	ptr = (STRU_CHANGE*)((char*)buf);
	printf("从字符数组中获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
	std::cout << ptr->D << std::endl;
        delete []buf;
        buf=nullptr;
	return 0;
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

转换前数据结构内容:  A=a,B=5,C=12.500000,D=hello
字符数组获取数据结构:A=a,B=5,C=12.500000,D=hello

我想到了另一个问题,如果期间把buf指针转换成其他数据类型的指针进行操作会有什么结果,我们知道,如果是普通的同类型指针互相赋值,那么不管是那个指针都会改变指针地址保存的值,不同类型的实际上也是一样的,实验如下。加入方法fun。

void fun(char *buf) //传入的是指针 即使类型转换 还是会变化
{
	STRU_CHANGE *temp = NULL;
	temp= (STRU_CHANGE*)((char*)buf);
	temp->A = 'A';
	printf("temp获取数据结构:A=%c,B=%d,C=%f,D=%s\n", temp->A, temp->B, temp->C, temp->D);
}
int main()
{
	STRU_CHANGE obj1;
	STRU_CHANGE *ptr=NULL;
	obj1.A = 'a';
	obj1.B = 5;
	obj1.C = 12.5;
	obj1.D = "hello";
	
	
	char *buf=new char[sizeof(STRU_CHANGE)];
	std::cout << sizeof(Score) << std::endl;
	std::cout<< sizeof(STRU_CHANGE) <<std::endl;
	printf("转换前数据结构内容:  A=%c,B=%d,C=%f,D=%s\n",obj1.A,obj1.B,obj1.C, obj1.D);
	//printf("字符数组获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
	memcpy(buf,&obj1,sizeof(obj1));

	fun(buf);//加入这个

	ptr = (STRU_CHANGE*)((char*)buf);
	printf("字符数组获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
	std::cout << ptr->D << std::endl;
        delete []buf;
        buf=nullptr;
	return 0;
}
12
48
转换前数据结构内容:  A=a,B=5,C=12.500000,D=hello
temp获取数据结构:A=A,B=5,C=12.500000,D=hello
字符数组获取数据结构:A=A,B=5,C=12.500000,D=hello
hello

发现temp和最后的答案都变了,验证了假设。

结构体中嵌套结构体

// 结构体转换.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
工作需要将postgres源码中的结构体
*/
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>

typedef struct Score
{
	int math;
	int chinese;
	int english;
	//int physics;
	//int chemistry;
	//int biology;
	Score() = default;
	Score(int m, int c, int e) :math(m), chinese(c), english(e)
	{

	}
	/*
	void print()
	{
		printf("math:%d,chinese:%d,english:%d\n", math, chinese, english);
	}
	*/
}Score;


//如果在未加字节对齐的情况下,那么需要字节对齐,
//那么直接将结构体取地址后复制到另一个数组中,实际上所需占用的内存大小是8个byte。

typedef struct STRU_CHANGE
{
	Score sco;
	unsigned char A;
	unsigned int B;
	float C;
	char *D;//有了非静态const属性 默认构造函数会被删除
	STRU_CHANGE() = default;

}STRU_CHANGE;

int main()
{
	STRU_CHANGE obj1;
	STRU_CHANGE *ptr;
	Score temp(1,2,3);
	obj1.sco = temp;
	obj1.A = 'a';
	obj1.B = 5;
	obj1.C = 12.5;
	obj1.D = new char[6];
	strcpy(obj1.D, "hello");

	char *buf = new char[sizeof(STRU_CHANGE)];
	//std::cout << sizeof(Score) << std::endl;
	std::cout << sizeof(STRU_CHANGE) << std::endl;
	printf("转换前数据结构内容:score:math=%d,score:chinese=%d,score:english=%d,A=%c,B=%d,C=%f,D=%s\n",obj1.sco.math, obj1.sco.chinese, obj1.sco.english, obj1.A, obj1.B, obj1.C, obj1.D);
	memcpy(buf, &obj1, sizeof(obj1));
	ptr = (STRU_CHANGE*)((char*)buf);
	std::cout << sizeof(*ptr) << std::endl;
	printf("从字符数组中获取数据结构:score:math=%d,score:chinese=%d,score:english=%d,A=%c,B=%d,C=%f,D=%s\n", ptr->sco.math, ptr->sco.chinese, ptr->sco.english, ptr->A, ptr->B, ptr->C, ptr->D);
	//std::cout << ptr->D << std::endl;
	delete[]buf;
	buf = nullptr;
	return 0;
}

28
转换前数据结构内容:score:math=1,score:chinese=2,score:english=3,A=a,B=5,C=12.500000,D=hello
28
从字符数组中获取数据结构:score:math=1,score:chinese=2,score:english=3,A=a,B=5,C=12.500000,D=hello

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值