结构体成员的内存分布以及大端小端

本文介绍了计算机中大端和小端存储模式的区别,并提供了判断系统字节序的方法。同时,文章详细讲解了结构体在内存中的字节对齐规则,通过union和struct实例展示了不同成员类型如何影响结构体的大小。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大端与小端:

小端:字节的低位放在内存低位地址,高位放在内存高位地址。

大端:字节的高位地址放在内存低位地址,低位放在内存高位地址。

判断系统是大端还是小端?

若判断处理器是Big还是Little模式,有两种方法。

1、

int i=1;   
    char *p=(char *)&i;   
    if(*p==1)     
           printf("小端");  
    else
           printf("大端");

          大小端存储问题,如果小端方式(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端

字节对齐:

结构体的对齐参

1.Union

#include<stdio.h>
typedef union 
{
char c[10];
char cc1;
}u11;//首先按照char c[10]分配10个字节,然后按照char的1个字节对齐,最终sizeof(u11)=10;
typedef union 
{
char c[10];
int i;
}u22;//首先按照char c[10]分配10个字节,然后按照char的4个字节对齐,最终sizeof(u11)=12;
typedef union 
{
char c[10];
double i;
}u33;//首先按照char c[10]分配10个字节,然后按照char的8个字节对齐,最终sizeof(u11)=16;
int main(void)
{
printf("sizeof(u11)%d\n",sizeof(u11));
printf("sizeof(u22)%d\n",sizeof(u22));
printf("sizeof(u33)%d\n",sizeof(u33));
return 0;
}

结果:

2.struct

#include<stdio.h>
struct{
short a1;
short a2;
short a3;
}A;//sizeof(short)=2,都是short,以2个字节整数倍对齐,最后为6.
struct{
long a1;
short a2;
}B;//sizeof(long)=4,sizeof(short)=2,以4个字节整数倍对齐,最后为8。
int main(void)
{
printf("sizeof(A)%d\n",sizeof(A));
printf("sizeof(B)%d\n",sizeof(B));
return 0;
}

结果:

编译器中提供了 #pragma pack(n)来设定变量以n 字节对齐方式。n字节对齐就是说变量存放的起始地址的 偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有 成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
下面举例说明其用法。
#pragma pack(push) //保存对齐状态
#pragma pack(4)//设定为4 字节对齐
struct test
{
char m1;
double m4;
int m3;
};
#pragma pack(pop)//恢复对齐状态
以上 结构体的大小为16,下面分析其存储情况,首先为m1分配空间,其 偏移量为0,满足我们自己设定的对齐方式(4 字节对齐),m1大小为1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof(double)大于4),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为4的倍数,m3占用4个字节。这时已经为所有 成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的 #pragma pack(4)改为#pragma pack(8),那么我们可以得到结构的大小为24。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值