自定义类型:结构体类型,枚举类型,联合类型

一、结构体

1、结构体类型的声明

  结构体是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
例如声明一个学生:

struct stu
{
	char name[10];//姓名
	char sex[5];//性别
	int age;//年龄
	
};

这里的stu是这个结构体的标签也可以叫做“名称”。当然我们也有特殊的声明,如下:

struct 
{
	char name[10];//姓名
	char sex[5];//性别
	int age;//年龄
	
}x;
struct 
{
	char name[10];//姓名
	char sex[5];//性别
	int age;//年龄
	
}a[10],*p;

那么如上中可以进行p = &x;这一操作吗?
注意!
编译器会把上面的两个声明当成完全不同的两个类型。
所以是非法的。!

2、结构体的自引用

自引用方式:

struct Node
{
 int data;
 struct Node* next;//**这里必须是指针方式,不然会造成内存溢出**
};

我们还要注意自引用的结构体标签“Node”,不可使用上面的不完全声明如下:

typedef struct
{
 int data;
 Node* next;
}Node;

注意上面的引用当方式是错误的!

3、结构体变量的定义与初始化

struct SN
{
	char c;
	int a;
}sn1 = {'w',50},sn2 = {.a = 456,.c = 'w'};//全局变量声明类型的同时定义变量,同时初始化变量。

小知识:
这里我么要注意上述中的s2的初始化,我们可以用“.”来不按顺序进行初始化。

4、结构体的内存对齐

这是一个需要深入讨论的问题:计算结构体的大小。
例如:

struct s1
{
 char c1;
 int i;
 char c2;
};
printf("%d\n", sizeof(struct S1));

打印出来是多少呢?

在这里插入图片描述
那么它是具体如何进行运算的呢?
那么就要引出他的对齐规则:

1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
3. 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
 VS中默认的值为8
 Linux中没有默认对齐数,对齐数就是成员自身的大小
4. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
5. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

5、修改默认对对齐数

#pragma pack(8)//设置默认对齐数为8
struct S1
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
//
#pragma pack(1)//设置默认对齐数为1
struct S2
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

二、枚举

1、枚举类型的定义

enum Sex
{
 MALE,
 FEMALE,
 SECRET
}

{}中的内容是枚举类型的可能取值叫做枚举常量
这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

enum Color
{
 RED=1,
 GREEN=2,
 BLUE=4
};

2、枚举的优点

我们可以使用 #define 定义常量,为什么非要使用枚举?

枚举的优点:
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
3. 便于调试
4. 使用方便,一次可以定义多个常量

三、联合(共用体)

1、联合类型的定义

类型说明:

联合也是一种特殊的自定义类型
这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。

例如:(我们把前面的结构体定义照搬过来)

union Un
{
	char c1;
	int i;
	char c2;
};
int main()
{
	union Un un;
	printf("%d\n", sizeof(un));
	return 0;
}

在这里插入图片描述
我们发现和前面的结构体的大小有所不同,正式联合体的特殊之处

2、联合体的特点

联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联
合至少得有能力保存最大的那个成员)。

union Un
{
	int i;
	char c;
};
union Un un;
int main()
{
	// 下面输出的结果是一样的吗?
	printf("%d\n", &(un.i));
	printf("%d\n", &(un.c));
	return 0;
}

在这里插入图片描述
可以看到两个的内存是相同的,所以这就是问什么联合类型也叫做共同体。

本章完!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值