自定义类型(结构,枚举,联合)

结构体(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.当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍;

猜你喜欢

转载自blog.csdn.net/QwQfeifei/article/details/81411907