struct 结构体大小的判断

本文通过几个C++结构体实例展示了不同成员变量排列顺序对结构体大小的影响,揭示了内存对齐规则如何影响结构体的实际大小。
#include 
using namespace std;
struct A
{
	char c;
};

struct B
{
	char c;
	int tmp;
};
struct C
{
	char c;
	char t[3];
	int tmp;
};
struct D
{
	int tmp;
	char c;
};
struct E
{
	int tmp;
	char c[4];
};
int main()
{
	cout<<sizeof(A)<<endl;
	cout<<sizeof(B)<<endl;
	cout<<sizeof(C)<<endl;
	cout<<sizeof(D)<<endl;
	cout<<sizeof(E)<<endl;
	return 0;
}

//结果分别为 
1
8
8
8
8
### C++ 中实现结构体大端与小端转换的方法 在 C++ 编程中,处理不同平台之间的二进制数据传输时,可能需要考虑字节序(Endianness)。常见的两种字节序分别是 **大端模式 (Big Endian)** 和 **小端模式 (Little Endian)**。为了确保跨平台兼容性,可以编写通用的代码来完成结构体中的字段从一种字节序到另一种字节序的转换。 以下是具体方法及其示例: #### 字节序基础知识 - 小端模式表示最低有效位存储在内存地址较低的位置。 - 大端模式表示最高有效位存储在内存地址较低的位置。 可以通过逐个字段进行字节交换的方式实现结构体的大端与小端转换[^1]。 --- ### 示例代码:结构体大小端转换 假设有一个简单的 `Person` 结构体如下所示: ```cpp #include <cstdint> #include <cstring> #pragma pack(push, 1) // 禁用结构体对齐 struct Person { uint8_t id; uint16_t age; uint32_t salary; }; #pragma pack(pop) ``` #### 实现大小端转换函数 通过手动操作每个字段的内容来进行字节顺序调整: ```cpp void swapEndian(Person& person) { // 对于单字节变量无需转换 // 对多字节数值类型使用标准库 std::byteswap 或者手写逻辑 person.age = ((person.age << 8) | (person.age >> 8)); // 手动翻转两个字节 person.salary = __builtin_bswap32(person.salary); // 使用内置指令翻转四个字节 } ``` 如果目标环境不支持上述内置函数,则可以用更普适的手工方式替换掉这些部分: ```cpp uint16_t byteswap_uint16(uint16_t value){ return (value << 8) | (value >> 8); } uint32_t byteswap_uint32(uint32_t value){ return ((value & 0xFF000000U) >> 24) | ((value & 0x00FF0000U) >> 8 ) | ((value & 0x0000FF00U) << 8 ) | ((value & 0x000000FFU) << 24); } // 修改后的版本 void swapEndian(Person& person) { person.age = byteswap_uint16(person.age); person.salary = byteswap_uint32(person.salary); } ``` 以上实现了将整个 `Person` 类型实例由当前机器默认字节序切换至相反字节序的功能。 注意,在实际应用过程中还需要检测运行所在系统的原始字节序以便决定是否执行该变换过程。这通常借助 union 及特定数值测试得出结论。 --- ### 自动判断并条件触发转换 下面展示如何自动判定系统原生字节序,并仅当必要时才调用前述换序功能: ```cpp union ByteOrderTestUnion{ uint32_t i; uint8_t c[4]; } test; bool isLittleEndian(){ test.i = 0x01020304; return test.c[0]==4 && test.c[1]==3 && test.c[2]==2 && test.c[3]==1 ; } int main() { bool little_endian = isLittleEndian(); Person p { .id=1 , .age=97 , .salary=5000 }; if(little_endian){ swapEndian(p); // 如果本机为little endian则需将其改为big endian形式发送出去或者保存起来供其他设备读取解析 } // 此处继续后续流程... } ``` 这样就可以保证无论是在何种架构上编译运行此程序都能得到一致的结果输出给外部接口或文件持久化层去消费了。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值