字节对齐、大小端问题

字节对齐

联合体的内存除了取最大成员内存外,还要保证是所有成员类型size的最小公倍数

结构体变量所占空间的大小必定是最宽数据类型大小的整数倍

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <bits/wordsize.h>  //

/*
struct union 字节对齐
*/

int main()
{
    long a;
    printf("long: %d\n", sizeof(a));

    short b;
    printf("short: %d\n", sizeof(b));
    // #pragma pack (4)  
    struct test 
    { 
    char b; 
    double c;
    int a;
    }st; // 12
    // #pragma pack ()
 
    //test st;

    #pragma pack(4)
    char *pucCharArray[10][10];

    int * p = NULL;
    printf("pointer: %d\n", sizeof(p));
    
    typedef union unRec{
        long   ulIndex;
        short  usLevel[9];  // 验证 “联合体的内存除了取最大成员内存外,还要保证是所有成员类型size的最小公倍数”
        char   ucPos;
    }REC_S;	
    REC_S  stMax,*pstMax;
    #pragma pack()

    printf("st: %d\n", sizeof(st));

    printf("REC: %d %d %d\n", sizeof(pucCharArray), sizeof(stMax), sizeof(*pstMax)); // 800  16 16 

    typedef struct node1
    {
        int a;
        char b;
        short c;
    }S1;

    printf("S1: %d\n", sizeof(S1));

    typedef struct node3
    {
        char a;
        S1 node;
        short b;
    }S3;

    printf("S3:%d\n", sizeof(S3));
    return 0;
}
字节序大小端

大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,地址由小向大增加,而数据从高位往低位放;

小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,高地址部分权值高,低地址部分权值低,和我们的日常逻辑方法一致。

操作系统常见小端,通讯协议常见大端

0x12345678

大端模式:

高位 -----------------> 低位

0x78 | 0x56 | 0x34 | 0x12

小端模式:

高位 ------------------> 低位
0x12 | 0x34 | 0x56 | 0x78
  • BLendian.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

/*
大小端字节序  数组  联合体

0x12345678

大端模式:
高位 -----------------> 低位

0x78 | 0x56 | 0x34 | 0x12

小端模式:
高位 ------------------> 低位
0x12 | 0x34 | 0x56 | 0x78
*/

/*************************** 大小端转换函数 *****************************/
typedef unsigned int    UINT32;
typedef unsigned short  UINT16;

// 宏
#define BSWAP_16(x)\
    (UINT16)(\
        (((UINT16)(x) & 0xff00) >> 8) | \
        (((UINT16)(x) & 0x00ff) << 8) \
    )

// 函数
UINT16 bswap_16(UINT16 x)
{
    return (((UINT16)x & 0xff00) >> 8) | (((UINT16)x & 0x00ff) << 8); 
}

UINT32 bswap_32(UINT32 x)
{
    return (((UINT32)x & 0xff000000) >> 24) | 
           (((UINT32)x & 0x00ff0000) >> 8) | 
           (((UINT32)x & 0x0000ff00) << 8) | 
           (((UINT32)x & 0x000000ff) << 24);
}
/*************************************************************************/

int main()
{
    int a = 1;
    char *p = (char*)&a;
    printf("0x%04x\n", *p);
    
    if(1 == *p)
    {
        printf("little endian\n");
    }else{
        printf("big endian\n");
    }
    
/********** 利用 union 判断大小端 ****************/
    union{
        short i;
        char c[2];
    }un;

    un.c[0] = 0x0a;
    un.c[1] = 0x01;

    printf("0x%04x\n", un.i);   // 大端 0x0a01  小端 0x010a

/********** 通过直接查看内存中的值 *********/
	short i = 0x1122;
	char *c = (char*)(&i);
	printf ("0x%x\n", *(c + 0)); //大端为 0x11 小端为 0x22
	printf ("0x%x\n", *(c + 1));


/************* 大小端转换 **************/
    printf("0x%x\n", bswap_32(0x12345678));
    printf("0x%x\n", BSWAP_16(0x1122));

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值