C语言学习笔记——自定义类型章节

学习小结

c语言自定义类型的学习笔记汇总

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

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//结构体
//结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量

//声明一个结构体类型
//struct Stu
//{
//	char name[20];
//	char tele[12];
//	char sex[10];
//	int age;
//
//}s4, s5, s6;
//struct Stu s3;//全局变量
//int main()
//{
//	//创建的结构体变量 s1 s2
//	struct Stu s1;
//	struct Stu s2;
//	return 0;
//}

//匿名结构体类型(不建议使用)
//struct
//{
//	char tele[12];
//	char sex[10];
//	int age;
//}sa;
//struct
//{
//	char tele[12];
//	char sex[10];
//	int age;
//}*psa;//变成结构体指针
//int main()
//{
//	psa = &sa;//(不合法,不合规矩的)
//	//编译器会把上面的两个声明当成完全不同的两个类型,所以是非法的
//	return 0;
//}

//结构体的自引用
//struct Node
//{
//	//数据域
//	int date;
//	//指针域
//	struct Node* next;//存放下一个节点的地址
//};
//int main()
//{
//	sizeof(struct Node);
//	return 0;
//}
//注意:结构体的自引用不能包含结构体本身的类型,可以用地址代替

//结构体类型重命名
//typedef struct Node
//{
//	int date;
//}Node;
//int main()
//{
//	struct Node n1;
//	Node n2;
//	//以上两种写法都可以
//	return 0;
//}

//结构体变量的定义和初始化
//struct Point
//{
//	int x;
//	int y;
//}p1;              //声明类型的同时定义变量p1
//struct Point p2;  //定义结构体变量p2

//struct T
//{
//	double weight;
//	short age;
//};
//struct S
//{
//	char c;
//	int a;
//	double d;
//	char arr[20];
//	struct T st;
//};
//int main()
//{
//	//结构体的初始化与结构体成员的访问
//	//struct S s = { 'c',100,3.14,"hello bit"};
//	//printf("%c %d %lf %s", s.c, s.a, s.d, s.arr);//c 100 3.140000 hello bit
//
//	//结构体中使用结构体
//	struct S s = { 'c',100,3.14,"hello",{55.6,30} };
//	printf("%lf", s.st.weight);//55.600000
//
//	return 0;
//}

//结构体内存对齐
//struct S1
//{
//	char c1;
//	int a;
//	char c2;
//};
//struct S2
//{
//	char c1;
//	char c2;
//	int a;
//};
//int main()
//{
//	struct S1 s1 = { 0 };//将所有值初始化为0
//	printf("%d\n", sizeof(s1));//12
//	struct S2 s2 = { 0 };
//	printf("%d\n", sizeof(s2));//8
//
//	return 0;
//}

//例题
//typedef struct s3
//{
//	double d;//双精度浮点数大小为8个字节
//	char c;//字符大小为1个字节
//	int i;//整形四个字节
//}s3;
结构体嵌套问题
//typedef struct s4
//{
//	char c1;
//	s3 c2;
//	double d;
//}s4;
//int main()
//{
//	printf("%d\n", sizeof(s3));//16
//	printf("%d\n", sizeof(s4));//32
//	return 0;
//}
//注意
//1、第一个成员在结构体变量偏移为0(相差0)的地址处
//2、其他成员变量要对齐到某个数字(对其数)的整数倍的地址处
//注意:对齐数指:编译器默认的一个对齐数与该成员大小的较小值
//vs编译器的值为8
//3、结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
//4、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

//修改默认对齐数
//#pragma pack(4)//设置默认对齐数为4
//struct S
//{
//	char c1;//1
//	//7 浪费了7
//	double d;//8
//};
//#pragma pack()//取消设置的默认对齐数
//int main()
//{
//	struct S s;
//	printf("%d\n", sizeof(s));//12 如果不加pragma的结果是16
//	return 0;
//}

//#pragma pack(1)//设置默认对齐数为1
//struct S
//{
//	char c1;//1
//	//7 浪费了7
//	double d;//8
//};
//#pragma pack()//取消设置的默认对齐数
//int main()
//{
//	struct S s;
//	printf("%d\n", sizeof(s));//9
//	return 0;
//}
//注意:结果在对齐方式不合适的时候,我们可以自己更改默认对齐数

//Offsetof宏 用于计算结构体成员的偏移
//格式offsetof(struct Name, memberName);
//#include<stddef.h>
//struct S
//{
//	char c;
//	int i;
//	double d;
//};
//int main()
//{
//	printf("%d\n", offsetof(struct S, c));//0
//	printf("%d\n", offsetof(struct S, i));//4
//	printf("%d\n", offsetof(struct S, d));//8
//	return 0;
//}

//结构体传参
//struct S
//{
//	int a;
//	char c;
//	double d;
//};
//void Init(struct S* ps)
//{
//	ps->a = 100;
//	ps->c = 'w';
//	ps->d = 3.14;
//}
//void Print1(struct S tmp)//因为只是打印,不需要修改
//{
//	printf("%d\n", tmp.a);//100
//	printf("%c\n", tmp.c);//w
//	printf("%lf\n", tmp.d);//3.140000
//}
//void Print2(struct S* ps)
//{
//	printf("%d\n", ps->a);//100
//	printf("%c\n", ps->c);//w
//	printf("%lf\n", ps->d);//3.140000
//}
//int main()
//{
//	struct S s;
//	Init(&s);//结构体传参对s的内容进行初始化
//	Print1(s);
//	Print2(&s);
//
//	s.a = 100;
//	s.c = 'w';
//	s.d = 3.14;
//	printf("%d\n", s.a);//100
//	printf("%c\n", s.c);//w
//	printf("%lf\n", s.d);//3.140000
//	return 0;
//}

//位段
//位段的声明和结构是类似的,有两个不同
//1、位段的成员必须是int,unsugned int或signed int或者char(整形家族类型)类型
//2、位段的成员名后边有一个冒号和一个数字
//struct S
//{
//	int a : 2;//意思是a只需要两个比特位的内存存储就可以了,以下同理
//	int b : 5;
//	int c : 10;
//	int d : 30;
//	//总共48个比特位
//};
//int main()
//{
//	struct S s;
//	printf("%d\n", sizeof(s));//8
//	return 0;
//}
//位段的内存分配
//位段的空间是按照需要以四个字节(int)或者1个字节(char)的方式来开辟的
//struct S
//{
//	char a : 3;
//	char b : 4;
//	char c : 5;
//	char d : 4;
//};
//int main()
//{
//	struct S s;
//	s.a = 10;
//	s.b = 20;
//	s.c = 3;
//	s.d = 4;
//	printf("%d\n", sizeof(s));//3
//	return 0;
//}
//注意:跟结构体相比,位段可以达到同样的效果,但是可以很好节省空间,但是有跨平台的问题存在

//枚举
//枚举顾名思义就是——列举
//枚举类型的定义
//enum Day//星期  枚举类型
//{
//	//枚举的可能取值 - 常量
//	Mon,
//	Tues,
//	Wed,
//	Thur,
//	Fri,
//	Sat,
//	Sun
//};
//enum Sex//枚举类型
//{
//	//枚举的可能取值
//	boy=2,
//	girl
//};
//enum Color
//{
//	Ret,
//	Green,
//	Blue
//};
//int main()
//{
//	//赋值只能赋予枚举列表中的元素
//	enum Sex s = boy;
//	s = girl;
//	enum Color c = Blue;
//	printf("%d %d %d\n", Ret, Green, Blue);//0 1 2
//	printf("%d %d\n", boy, girl);//2 3
//	//注意:枚举列表中的元素第一个默认从零开始,依次往下增加1(默认情况下)
//	return 0;
//}

//联合 - 联合体(共用体)
//联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合体也叫共用体)
//
//union Un
//{
//	char c;
//	int i;
//};
//int main()
//{
//	union Un u;
//	printf("%d\n", sizeof(u));//4
//	printf("%p\n", &u);   //00000061764FF7F4
//	printf("%p\n", &u.c); //00000061764FF7F4
//	printf("%p\n", &u.i); //00000061764FF7F4
//	//特征是这些成员共用同一块空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少有能力保存最大的那个成员)
//	//同等时间内只能用一个
//	return 0;
//}
//注意:联合体的大小至少是最大成员的大小

//判断大小端
//第一种
//int main()
//{
//	int a = 1;
//	if (*(char*)&a == 1)
//	{
//		printf("小端");
//	}
//	else
//	{
//		printf("大端");
//	}
//	//低地址                        高地址
//	//……[][][][11][22][33][44][][][]…… 大端存储模式
//	//……[][][][44][33][22][11][][][]…… 小端存储模式
//	return 0;
//}
//第二种
//int chack_sys()
//{
//	union Un
//	{
//		char c;
//		int i;
//	}u;//利用联合体共用同一块空间的特点实现
//	u.i = 1;
//	return u.c;//返回第一个字节
//	//返回1是小端
//	//返回0是大端
//}
//int main()
//{
//	int ret = chack_sys();
//	if (ret == 1)
//		printf("小端");
//	else
//		printf("大端");
//	return 0;
//}

//union Un
//{
//	int a;//4
//	char arr[5];//5
//};
//int main()
//{
//	union Un u;
//	printf("%d\n", sizeof(u));//8 内存对齐
//	return 0;
//}
//联合体大小的计算
//联合体的大小至少是最大成员的大小
//当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍

以上代码均在vs2022环境下编译

猜你喜欢

转载自blog.csdn.net/qq_72935001/article/details/126375062