C的字節對齊和位域操作

1、 字節對齊

首先分析字節對齊之前,需要了解概念

  1. 自身對齊:數據結構自身的大小
  2. 指定對齊:編譯器或者用戶指定的值,例如__attribute__ ((aligned (1))),設置爲單字節對齊
  3. 有效對齊:取自身對齊和指定對齊中較小的

分析結構體佔用內存大小要看以下兩個條件

  1. 對於結構體或者類,要將其補齊爲其有效對齊值的整數倍,結構體的有效對齊值是其最大數據成員的有效對齊值
  2. 存放成員的起始地址必須是該成員有效對齊值的整數倍

對於位域操作而言,我們需要關心如下:

a. 位域變量的長度不能大於其類型的長度sizeof(類型) ,例如bit_a中char a:10是不行的
b. 位域可以是無名位域,無名位域只能用作填充或調整位置,不能使用
c. 位域結構體的大小必須是其最長基本類型大小的整數倍sizeof(類型),參見foo4
d. 當一個字節不夠放時,可以另起一個字節,也可以有意重新起一個字節,例如如bs
f. 當結構體中有非位域操作時,整個結構體不進行壓縮,建test3

例子1:

struct bs     
{     
    unsigned a:4     
    unsigned :0 /*空域*/     
    unsigned b:4 /*從下一單元開始存放*/     
    unsigned c:4     
}

例子2:

struct foo4 {
    char    a : 2;
    char    b : 3;
    int c : 1;
};  //大小爲4

2. 位對齊(__attribute__使用)

按照bit位,內存是連續的,配合__attribute__使用,GNU使用__attribute__選項來設置,例如下面例子中,Test1使用一位對齊

  1. attribute ((aligned (n))),按照n字節對齊
  2. attribute ((packed)),對於域是位對齊
#include <stdio.h>
#include <stdlib.h>
typedef struct Test3
{
    char a:1;
    int b:2;
    long c;
}test3;
typedef struct Test2
{
    char a:1;
    int b:2;
    int :1;
}test2;
struct bit{
int a:4; 
int b:4;
char c:4;
char d:4;
}bit1; //默認字節對齊
struct bit_a
{
	char a:5;
	char b:5;
	char c:5;
	char d:5;
	char e:5;
}__attribute__ ((packed)) bit_a1; //位對齊
struct bit_aa
{
	char a;
	int b;

}__attribute__ ((packed)) bit_aa; //位對齊
typedef struct Test1
{
    char a:1;
    short b:2;
}__attribute__ ((aligned (1))) test1; //單字節對齊
int main(int argc, char* argv[])
{

	fprintf(stderr,"%ld\n %ld\n %ld\n %ld\n %ld\n %ld\n",sizeof(test3),sizeof(test2),sizeof(bit1),sizeof(bit_a1),sizeof(bit_aa),sizeof(test1));
	exit(0);

}


~/Videos$ ./io_1
16
 4
 4
 4
 5
 2
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章