字节对齐
联合体的内存除了取最大成员内存外,还要保证是所有成员类型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;
}