C语言自定义类型( 结构体,联合体,枚举)

C语言自定义类型

结构体

  • 什么是结构体
    • 与数组相似,数组是相同类型变量的集合,而结构体是不同类型变量的集合
    • 结构体的各个成员会占用不同的内存,互相之间没有影响;
    • 结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙)
  • 如何创建结构体
struct 结构名
{
    //结构体成员: 变量
}//结构体一般描述是一系列事物的抽象,即某个事物的某些特征属性
  • 结构体有什么作用:充当记录复杂数据功能
    • 定义一个结构体变量
      • 普通结构体变量: 类型 变量名;
      • 指针变量: 类型* 变量名;
      • 数组: 类型 数组名[数组长度];
struct 结构名 变量名;//定义一个普通结构体
struct 结构名* 变量名;//定义一个结构体指针
struct 结构名 数组名[数组长度];//定义一个结构体数组
如果只给结构体定义一两个变量,也可以在定义结构体的同时定义结构体变量,如:
struct Student
{
	char name[20];//姓名
	int age;//年龄
	char gender[3];//性别
}student1,student2;
typedef和结构体
当定义结构体的时候在struct前面加typedef,并在最后加一个别名,如:
typedef struct Student
{
	char name[20];//姓名
	int age;//年龄
	char gender[3];//性别
}Student;
这样的话当定义结构体变量时就可以直接用别名代替struct Student如:
Student student;

  • 如何访问结构体中数据
    • 结构体中数据只能通过结构体变量访问(当然指针算是特殊结构体变量,数组也算特殊结构体变量)
    • 访问方式只有两种
      • 变量.成员
      • 指针->成员 ->:指针指向运算符
  • 结构体变量的初始化
    • 定义的初始化,必须类型上要和成员顺序一致
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<assert.h>
//小明 20 男
//小蓝 21 男
//小红 19 女

struct Student
{
	char name[20];//姓名
	int age;//年龄
	char gender[3];//性别
};
int main()
{
	//No.1 定义变量
	//先创建后初始化
	//前缀的含义是主体,表示整个成员是谁,如下就表示学生的姓名,学生的年龄,学生的性别
	struct Student student = { "name",20,"男" };
	printf("%s %d %s\n", student.name, student.age, student.gender);
	strcpy_s(student.name, 20, "小明");//字符数组不能直接复制
	student.age = 20;
	strcpy_s(student.gender, 3, "男");
	printf("%s %d %s\n", student.name, student.age, student.gender);

	//No.2 用户输入结构体变量
	struct Student student0;
	printf("请输入学生的姓名 年龄 性别:\n");
	scanf_s("%s%d%s", student0.name, 20, &student0.age, student0.gender, 3);
	printf("%s %d %s\n", student0.name, student0.age, student0.gender);

	//No.3 结构体数组--->一般用来管理表格数据
	struct Student student1[3]={0};
	printf("请输入三个学生的姓名 年龄 性别:\n");
	for (int i = 0; i < 3; i++)
	{
		scanf_s("%s%d%s", student1[i].name,20, &student1[i].age, student1[i].gender,3);
	}
	for (int i = 0; i < 3; i++)
	{
		printf("%s\t%d\t%s\n", student1[i].name, student1[i].age, student1[i].gender);
	}

	//No.4 指针
	struct Student* student2 = NULL;
	//p->age = 12;   //错误,空里面没有这个age
	//结构体指针变成结构体变量

	//4.1 指向普通变量
	student2 = &student;
	printf("%s %d %s\n", student2->name, student2->age, student2->gender);

	//4.2 动态内存申请
	struct Student* student3 = (struct Student*)malloc(sizeof(struct Student));
	assert(student3);
	printf("请输入学生的姓名 年龄 性别:\n");
	scanf_s("%s%d%s", student3->name, 20, &student3->age, student2->gender,3);
	printf("%s\t%d\t%s\n", student3->name, student3->age, student2->gender);
	free(student3);
	student3 = NULL;
	return 0;
}

联合体(共用体)

  • 大家基本不用,但是网络库中有

  • 什么是联合体(共用体)

    • 共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
    • 共用体占用的内存等于最长的成员占用的内存。
    • 共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
  • 如何创建 联合体(共用体)

//先定义共用体,再创建变量
union 共用体名
{
    成员列表
};
union 共用体名 变量名;
//定义共用体的同时定义变量
union 共用体名
{
    成员列表
}变量名;
//如果不再定义新的变量,也可以将共用体的名字省略
union
{
    成员列表
}变量名;
  • 例子
#include <stdio.h>
#include <stdlib.h>
//联合体:共用体
union  MM
{
	char name[20];
	int age;
};

int main()
{
	//所有数据成员用的是同一段内存,最长的那个变量的内存
	//所以定义的时候不能直接初始化两个数据
	//任何时候共用体只有一个数据有效
	union MM mm = { "A" };
	//union MM mm2 = { "A" ,68};  //错误的写法
	printf("%d\n", mm.age);
	//union MM mm2 = { 68 };   //00 00 00 44    //44 00 00 00
	//printf("%s", mm2.name);
	printf("%d %d\n", (int)sizeof(mm), (int)sizeof(union MM));
	return 0;
}

枚举

  • 什么是枚举
    • 枚举与宏定义作用一样,只不过当用宏定义时宏名过多时,代码松散,看起来总有点不舒服
    • 枚举类型就是一个常量,就是整数
    • 增加代码可读性,防止幻数–>大量的常量
  • 枚举与宏定义的区别
    • 宏在预处理阶段将名字替换成对应的值
    • 枚举在编译阶段将名字替换成对应的值
  • 如何定义一个枚举类型
enum 枚举名
{
//枚举内容
};
//拿星期来举例
//默认初始化: 从0开始依次初始化为0,1,2...
enum week{ Mon,Tues, Wed, Thurs, Fri, Sat, Sun};

//也可以给每个名字都指定一个值
enum week{ Mon=1,Tues=2, Wed=3, Thurs=4, Fri=5, Sat=6, Sun=7};

//当给第一个数赋值1,那么后面的会自动依次赋值2,3,4...
enum week{ Mon=1,Tues, Wed, Thurs, Fri, Sat, Sun};

//当给一部分赋值时,那么会对于已赋值的部分后面依次赋值,即下一行枚举定义会初始化赋值为1,2,3,7,8,9,10
enum week{ Mon=1,Tues, Wed, Thurs=7, Fri, Sat, Sun};
  • 枚举是一种类型,所以也可以用它来定义枚举变量,定义的方法与上面的结构体,共同体一样
//枚举是一种类型,通过它可以定义枚举变量:
enum week a, b, c;
//也可以在定义枚举类型的同时定义变量:
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a, b, c;
//有了枚举变量,就可以把列表中的值赋给它:
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun };
enum week a = Mon, b = Wed, c = Sat;
//或者:
enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } a = Mon, b = Wed, c = Sat;
  • 例子
#include <stdio.h>
#include <stdlib.h>
//enum 枚举类型名{符号1,符号2,...};
enum COLOR{Red,Green,Blue,Yellow};
//枚举类型就是一个常量,就是整数
//默认初始化: 从0开始一次初始化
//增加代码可读性,防止幻数-->大量的常量
//手动初始化
enum  Eement {Wall=1,Road=0,Box=4,End=3,People=5};
//部分初始化,部分默认
//不写的是写了+1
enum NUM {a=1,b,c=4,d};
//b=a+1:2
//d=c+1:5
void print(int num) 
{
	printf("%d\n", num);
}
//C语言把枚举理解int
void printEnum(enum COLOR cnum) 
{
	printf("%d\n", cnum);
}
//enum class
int main() 
{

	printf("red:%d\n", Red);
	printf("Green:%d\n", Green);
	printf("Blue:%d\n", Blue);
	printf("Yellow:%d\n", Yellow);
	printf("%d\t%d\t%d\t%d\n", a, b, c, d);
	print(Red);
	printEnum(a);
	printEnum(1);
	return 0;
}

位段

  • 一般用于嵌入式
#include <stdio.h>
//特殊的结构体:内存精确到二进制位
//作用:节省内存
struct Data 
{
	unsigned int a : 3;  //_ _ _   000  111:7
	unsigned int b : 1;  //0 1
	unsigned int c : 4;  //0000 1111:15
};
//寄存器的描述
//标志位
//12*4=48
//4个字节

int main()
{
	struct Data data = { 8,1,18 };
	printf("%d,%d,%d", data.a, data.b, data.c);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值