自定义类型部分知识

>结构体类型创建 

第一种方法:
struct A{
    int a;
    char b;
}

第二种方法:
typedef struct B{
    int a;
    char b; 
}B

结构体的自引用:
typedef struct B{
    int a;
    char b; 
    sutuct B *b;//指针的大小是确定的
}B

>结构体初始化 

结构体允许整体初始化,不允许整体赋值;
例如:struct A a1={2,'s'};//正确
      struct A a2;
      a2={2,'s'};//错误
      a2.a=2;a2.b='c';//正确赋值

>结构体内存对齐 

为什么要对齐?

《Windows核心编程》里这样说:当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。在最好的情况下,是两倍的时间,有时更长。

对齐原则:

原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。

原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)

原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
linux 默认#pragma pack(4), 
window 默认#pragma pack(8)。 
#pragma pack(1)不使用对齐
#pragma pack()恢复到默认对齐

>位段,位段计算机大小
位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为"位段"或称"位域"( bit field) 。利用位段能够用较少的位数存储数据。
32位的计算机位段为32字节;
位段的定义方式:
int a:2,b:3;//在一个存储单元
int :0;//是下一个位段从下一个存储单元存放

int b:1;//另一个存储单元


>枚举+联合
枚举
是一个被命名的整型常数的集合,本质还是整型;
内部成员第一个默认值是0,后边依次+1;
例如
enum A{
a,//默认值是0
b,//1
c,//2
d,//3
e//4
}
enum A{
a=10,//10
b,//11
c=20,//20
d,//21
e//22

}

联合体:
在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。

union number
{                   /*定义一个联合*/
int i;
struct
{             /*在联合中定义一个结构*/
         char first;
         char second;
}half;
}num;
num.i=0x4241;         /*联合成员赋值*/
printf("%c%c ", num.half.first, num.half.second);
num.half.first='a';   /*联合中结构成员赋值*/
num.half.second='b';
printf("%x ", num.i);
输出结果为: 
AB 
6261 
原文地址:https://www.cnblogs.com/yongtaochang/p/13615384.html