Fork me on Github Fork me on Gitee

C温故补缺(九):字节对齐与排序

字节对齐与排序

字节对齐的原因与字节排序

取自:VisualEther
原文档下载:Gitee

_packed

_packet用于结构体中变量在内存中的对齐.如

typedef struct test_s{
   int i;
   char a[3];
   char b[5];
   char c;
}test_t;

如果按默认对齐方式,不足四字节的按四字节算,那么,

int+char[3]+char[5]+char=24个字节

如果用_packet对齐,就是13个字节

但是在VS2008以后就弃用了这个功能

位域

位域:是定义在结构体中的指定了变量宽度的变量 (变量宽度的单位是bit/位)

#include<stdio.h>
struct data{
    int i;
    int j;
}d;
struct Data{
    int i:1;
    int j:1;
}D;

int main(){
    printf("%d ",sizeof(d));
    printf("%d ",sizeof(D));
    printf("\n");
}

输出的结果是8和4

int型占4个字节,但指定两位的位域后,输出的却是4个字节?

因为C语言有默认的对齐方式,段内按4字节对齐,所以虽然Data只用了两位,仍要申请4字节的内存

所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

格式:

struct 位域结构名 {

 位域列表
 type [member_name] : width ;
 ...
};

type:只能是int,unsigned int和signed int三种

一般说,一个位域只能在一个字节中,一个字节可以有多个位域,有时为了对齐,会填充空位域

struct bs{
    unsigned a:5;
    unsigned  :3;    /* 空域 */
    unsigned b:4;    /* 从下一单元开始存放 */
    unsigned c:4
}

如bs的第一个字节只存放a这一个位域,剩下的3位放不下b,c,所以用空位域对齐

位域调用类似结构体变量,用' . '或' -> '成员运算符

posted @ 2022-11-12 15:47  Tenerome  阅读(88)  评论(0编辑  收藏  举报