结构体(struct):
1定义:结构体是一些值的合集,这些值称为成员变量,结构的每个成员变量可以有不同的类型;
eg:struct tag //tag结构体标签
{
char name[10]; //名字
int age; //年龄
char gender[3]; //性别
}; //分号不能丢
在结构体声明的时候,可以省略结构体标签tag
2.结构体的成员:标量,数组,指针,甚至其他结构体
3.结构体成员的访问:1.结构体是通过点操作符(.)访问的,点操作符接受两个操作数;
struct Stu
{
char name[20];
int age;
};
struct Stu s; //定义结构体变量
strcpy(s.name, "zhangsan"); //使用.访问name成员
s.age = 20; //使用.访问age成员
2.结构体访问得到不是结构体变量,而是一个指向结构体的指针;
struct S
{
char name[20];
int age;
}s;
void print(struct S* ps)
{
printf("name=%s age=%d\n", (*ps).name, (*ps).age);
printf("name=%s age=%d\n", ps->name, ps->age);
}
4.结构体的自引用:
1. struct Node
{
int data;
struct Node next;(修改:struct Node* next;)
};
2.typedef struct (修改:typedef struct Node)
{
int data;
Node* next; (修改:struct Node* next;)
}Node;
5.结构体的定义和初始化
struct Point
{
int x;
int y;
}p1; //声明并同时定义
struct Point p2; //定义结构体变量p2
struct Point p3 = { 3, 5 };
struct Stu //类型声明
{
char name[20];
int age;
};
struct Stu s = { "zhangsan", 20 };//初始化
嵌套初始化
struct Point
{
int x;
int y;
}p1; //声明并同时定义
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = { 10, {2,3},NULL };//结构体嵌套初始化
6. 结构体的内存对齐
(1)对齐规则:1.第一个成员在结构体变量偏移量为0的位置;
2.其他成员变量对齐到某个数字(对齐数)的整数倍地址处
对齐数=编译器默认与该成员大小较小值
(vs默认为8,linux默认为4)
3.结构体总大小为最大对齐数的整数倍;
4.如果嵌套了结构体,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体大小就是所有对齐数(包含嵌套结构体的对齐数)整数倍。
(2)出现的原因:平台原因(移植):不是所以平台都可以访问任意地址的数据,有的只能取特定的数据类型;
性能原因:未对齐的内存,处理器需要两次访问;
(3)内存对齐就是空间换取时间
(4)建议在设计结构体时,让空间小的成员集中在一起
7.结构体传参:
结构体传参一般传结构体地址:
原因:函数传参,参数需要压栈,如果传递一个结构体的话,结构体过大,压栈的操作开销比较大影响性能;
位段
定义:位段和结构体类似,两点区别 :1.位段成员必须是int类型(int,signed int,unsigned int)
2.位段的成员名后边有一个冒号和数字;
eg: struct A
{
int _a : 3;
int _b : 5;
};
位段的内存分配:1.位段的成员可以是int unsigned int signed int char (整形家族)类型
2.位段的空间上是按照4个字节或者一个字节来开辟的;
3.位段有很多不确定因素,所以不能跨平台;
位段的跨平台问题:
1.int被看作有符号还是无符号不确定;
2.位段中最大位数目不能确定,(16位最大16,32位最大32);
3.位段成员从左到右还是从右到左不清楚;
4.一个结构两个位段,第二个较大,无法容纳第一个,舍弃还是利用不清楚;
总结:位段与结构体相比,能够节省空间,但最大问题就是跨平台的问题;
枚举(enum):
定义:一一列举出来所有可能的值;
eg:enum Day
{
Mon, //逗号
Thus,
Wed, //枚举常量,都有值,默认从0开始,一次递增为1,定义时候可以赋初值;
};
枚举的优点:1.增加代码的可读性和可维护性;
2.和define定义的表示法相比,枚举有类型检查,严谨;
3.防止命名污染(分装);
4.便于调试;
5.使用方便,一次可以定义多个常量;
联合(union)
定义:这种类型的定义的变量包含一系列的成员,特征是这些成员共用一块空间
eg:union Un
{
char c;
int i;
};
union Un un; // 联合变量的定义
//计算大小
printf("%d\n", sizeof(un));
特点:联合的成员共用一块内存空间,这样一个联合变量的大小,至少是最大成员的大小;
大小计算:1.联合体大小至少是最大成员大小;
2.当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍;