对于结构体的知识点,我主要分为以下几点来讲解:结构体的声明、结构体类型的创建、结构体成员的访问、结构体的初始化、结构体内存对齐、位段。
1.结构体的声明
struct stu{
char name[20]; //名字
int age; //年龄
char sex[5]; //性别
char id[20]; //学号
}; //分号不能丢
2.结构体类型的创建
有两种创建的方法,第一种:
struct stu{
char name[20]; //名字
int age; //年龄
};
struct stu S1 ; //定义了一个结构体变量S1
第二种:
struct stu{
char name[20]; //名字
int age; //年龄
}S2; //定义了一个结构体变量S2
3.结构体成员的访问 -> 点操作符 (.)
创建了结构体变量之后,以上面创建的结构体变量为例,对于结构体变量的访问如下:
struct stu S1 ; //定义了一个结构体变量S1
strcpy(S1.name,"zhangsan"); //使用 . 访问name成员
S1.age=20; //使用 . 访问age成员
4.结构体的初始化
struct stu{
char name[20]; //名字
int age; //年龄
};
struct stu S3={"zhangsan",20}; //初始化:定义变量的同时赋初值
struct stu{
int data;
struct Poind p;
struct Node *next;
};
n1={10,{2,3},NULL}; //结构体嵌套初始化
struct stu n2={20,{5,6},NULL}; //结构体嵌套初始化
5.结构体内存对齐
首先得了解 结构体对齐规则:
1)第一个成员在与结构体变量偏移量为0的位置处。
2)其他成员变量要对齐到某个数字(对其数)的整数倍的地址处。对其数=编译器默认的一个对其数与该成员大小的较小者。
vs中默认的值是8
Linux中默认的值是4
3)结构体总大小为最大对其数(每一个成员变量都有一个对其数)的整数倍。
4)如果嵌套了结构体对齐到自己的最大对其数是整数倍处,结构体的整体大小就是最大对齐数(含嵌
套结构体的对齐数)的整数倍。
例如:
struct S1{
char c1 ;
int i ;
char c2 ;
};
printf("%d\n",sizeof(struct S1));//输出的是 12 .
struct S2{
char c1 ;
char c2 ;
int i;
};
printf("%d\n",sizeof(struct S));//输出的是 8.
总的来说,结构体的内存对齐是拿空间来换取时间的做法。
6.位段
位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是int 、unsigned int 、或signed int。
2.位段的成员名后边有一个冒号和一个数字。
比如:
struct A{
//位段是不跨平台的
int a:2;
int b:6;
int c:3;
int d:12;
};
A就是一个位段类型。
位段的内存分配:
- 位段的成员可以是int、 unsigned int 、 signed int或者是char(属于整型家族)类型
- 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的。
- 位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免使用位段。
位段的跨平台的问题:
- int位段被当成有符号数还是无符号数是不确定的。
- 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成17,在16位机器会出问题。)
- 位段中成员在内存中从左到右分配,还是从右到左分配标准尚未定义。
- 当一个结构包含俩个位段,第二个成员位段比较大,无法容纳第一个位段剩余的位时,是是舍弃还是利用,这是不确定的。
总结:跟结构相比,位段可以达到同样的效果,但是可以很好的节省空间,但有跨平台的问题存在。