关于结构体,位断,枚举,联合体相关的总结及内存对齐问题的探究

为什么要对齐内存?

    平台(移植)原因:访问任意地址上的任意数据并不是所有硬件平台都能做到的。一些平台只能在某些地址处取特定类型的数据.

    性能(硬件)原因:经过内存对齐之后,CPU对内存的访问速度就是大大提升。(访问未对齐的内存,CPU需要执行两次访问操作。而经过对齐之后的内存仅需要一次访问。)

    总结:内存对齐本质上就是通过牺牲空间来换取时间的做法。

内存分配规则:

        1)第一个成员在与结构体变量偏移量为0的地址处。

        2)从第二个成员开始,每个成员都要对齐它自身对齐数的整数倍地址。(每个成员的对齐数是自身的大小和默认对齐数的较小值,VS平台的默认对齐数是8,linux下是4。)

        3)结构体的总大小是整体中最大成员类型的整数倍。

如何修改默认对齐数?

    pragram pack(4);  //把默认对齐数修改为4。

    pragram pack();   //恢复环境默认对齐数。

    Windows下VS平台默认对齐数可修改为(1,2,4,8)。

    Linux环境下可修改为(1,2,4)。

1.结构体:

    1.1 示例

struct Stu  //结构体的类型为struct Stu,相当于int/float,struct后边的Stu不能丢
{
    int age=100000;
    char name="CrankyPants";
}student1;

        结构体在赋值的时候和数组很类似,但是有一点区别就是结构体如果在初始化的时候没有赋值,那么后期赋值就只能逐个元素进行赋值。


2、位断:

      2.1 示例

struct AAA
{ 
      int a:2; //”:“后边的2,表示位域的长度       
      int b:6; 
      int c:4; 
      int d:2; 
}data;

        2.2

            一个位域只能存在于一个字节之中,当一个字节中剩下的空间不足以存放另一个位域的时候,应从下一个单元起储存该位域。但是当有意要从下一个单元开始存储的时候,就可以通过创建一个空位域的方法来实现。比如:

        示例

struct BBB
{
    int a:2;
    int  :0;
    int b:6;
    int c:4;
    int d:2;
}deta2; // 此时位域所占空间为3个字节,相比上个位域多了一个字节。

        2.3

            因为位域不能跨字节存储,所以在定义位域的长度时不能超过平台中的默认对齐数。 (VS环境下的默认对齐数是8,linux环境下是默认对齐数是4。)

3、枚举:

      3.1 示例

enum Day
{
    Mon;
    Tues;
    Wed;
    Thur;
    Fri;
    Sat;
    Sun;
};

    3.2 枚举的应用

        枚举类型常量常用于循环变量控制,枚举常量则用于多路选择控制情况。

4、联合体:

      4.1 示例

union Data
{
    int i=0;
    char ch="A";
    float f=0.12;
}data;

     4.2 特点

        联合体中成员公用同一块内存,存在内存对齐,最后一次赋值有效。联合体的大小至少为最大元素的大小,但不一定是,联合大小是最大对齐数的最小整数倍。





猜你喜欢

转载自blog.csdn.net/crankypants/article/details/80252214