C语言自定义类型详解—(结构体、联合体、枚举、位段)

一、结构体

1.什么是结构体

结构体是C语言中重要的知识点之一,结构体使C语言有能力描述很多复杂的数据类型。

例如:当你要描述一个图书类型时单独使用某一种基本类型就不能很好的进行描述了,这时结构体就派上用场了,你可以这样表示一个图书类型:图书类型(书名(char)+书号(int)+价格(bouble)+作者(char))

2.结构体的声明

以图书类型为例,声明一个图书类型的结构体:

//结构体的声明
struct Book //struct 类型名字 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
};//这里的分号注意不要漏掉

注意:此时只是声明一个结构体,并未在内存中开辟空间

3.结构体变量的定义

定义结构体变量的方式有三种:

(1)先定义结构体,在定义结构体变量

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
};
struct Book book1, book2;//这里的book1和book2就是两个struct Book类型的结构体变量

(2)在定义结构体的同时定义结构体变量

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
} book1, book2;//这里的book1和book2就是在声明结构体的同时时定义的两个struct Book类型的结构体变量

 (3)直接定义结构体变量

struct 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
} book1, book2;//这里的book1和book2就是结构体变量

4.结构体成员的访问

访问结构体变量中的成员有两两种:

(1)通过 结构体变量名  . 结构体成员

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
};

int main()
{
	//定义结构体变量 book1
	struct Book book1;
	//通过 变量名 .结构体成员名字 可以访问到结构体里面的内容
	book1.BookName;
	book1.BookNum;
	book1.Author;
	book1.Price;
	return 0;
}

(2)通过 结构体指针 -> 结构体成员 

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	char BookNum[10];//书号
	double Price;//价格
	char Author[10];//作者
};

int main()
{
	//定义结构体变量 book2
	struct Book book2;
	//定义一个结构体指针变量 Pbook2
	struct Book *Pbook2;
	//把结构体 book2 的地址给结构体指针 Pbook2
	Pbook2 = &book2;
	//通过 结构体指针 -> 结构体成员名 访问
	Pbook2->BookName;
	Pbook2->BookNum;
	Pbook2->Author;
	Pbook2->Price;
	return 0;
}

 5.结构体赋值

(1)直接赋值

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	int BookNum;//书号
	double Price;//价格
	char Author[10];//作者
};

int main()
{
	//定义结构体变量 book
	struct Book book;
	//定义一个结构体指针变量 Pbook2
	struct Book* Pbook;
	//把结构体 book 的地址给结构体指针 Pbook
	Pbook = &book;
	//赋值
	scanf("%s", book.BookName);
	book.BookNum = 1000;
	Pbook->Price = 66.8;
	scanf("%s", book.Author);

	printf("%s %d %.2lf %s", book.BookName, book.BookNum, book.Price, book.Author);
	return 0;
}

运行结果: 

 (2)通过{ } 赋值

struct Book //struct 类型名字 
{
	char BookName[20];//书名
	int BookNum;//书号
	double Price;//价格
	char Author[10];//作者
};

int main()
{
	//定义结构体变量 book
	struct Book book = {"三国演义",10000,66.8,"罗贯中"};
	printf("%s %d %.2lf %s", book.BookName, book.BookNum, book.Price, book.Author);
	return 0;
}

运行结果:

二、联合体

1.什么是联合体

在C语言中,联合体(union)是一种特殊的数据类型,它允许在同一内存空间中存储不同类型的数据。联合体的定义使用关键字union

联合体的特点是,所有成员共用同一块内存,占用的空间大小为最大成员的大小。这意味着在任何时刻,联合体只能存储一个成员的值。当修改联合体的一个成员的值时,会影响其他成员的值。这是因为联合体的成员共享同一块内存。

2.联合体的声明

下面是一个联合体声明的示范:

//联合体声明
union Data //union 联合体名字
{
	int i;
	float f;
	char str[20];
};

在这个示例中,union Data 定义了一个联合体,它包含了一个整数 i,一个浮点数 f 和一个字符数组 str。这三个成员共用同一块内存。

3.联合体的访问和赋值 

使用联合体时,可以通过成员访问运算符.来访问联合体的成员。但是需要注意的是,只能同时存储一个成员的值。例如,可以通过以下方式赋值和访问联合体的成员:

//联合体声明
union Data //union 联合体名字
{
	int i;
	float f;
	char str[20];
};

int main()
{
	union Data data;
	data.i = 10;
	printf("data.i = %d\n", data.i);

	data.f = 3.14;
	printf("data.f = %f\n", data.f);

	strcpy(data.str, "Hello");
	printf("data.str = %s\n", data.str);
	return 0;
}

运行结果:

 

三、枚举

1.什么是枚举?

枚举(enum)是一种用户自定义的数据类型,用于定义一组具有离散取值的常量。枚举常量在枚举中被分配一个唯一的整数值,这些常量可以作为标识符在程序中使用。

2.枚举的声明

枚举的定义使用关键字enum,通常在函数外部定义。以下是一个枚举的示例: 

enum Weekday  //enum 枚举常量名
{
	MON, //0
	TUE, //1
	WED,
	THU,//...
	FRI,
	SAT,
	SUN//6
};

在这个示例中,enum Weekday 定义了一个名为 Weekday 的枚举类型,它包含了七个枚举常量,分别代表星期一到星期日。这些常量是由系统依次分配的整数值,从0开始递增。 

 3.枚举类型的使用

枚举常量可以在程序中以常量的形式使用,例如:

enum Weekday today;
today = WED;

在代码中使用枚举常量时,可以直接引用它们的名称。上述代码将一个枚举常量 WED 赋值给变量 today。

可以为枚举常量显式指定整数值,例如:

enum Month {
    JAN = 1,
    FEB,
    MAR,
    APR,
    MAY,
    JUN,
    JUL,
    AUG,
    SEP,
    OCT,
    NOV,
    DEC
};

 在这个示例中,枚举常量 JAN 被显式指定为1,后续的枚举常量会依次递增。这样可以灵活地定义枚举常量的取值。

注意:枚举在C语言中常用于定义一组具有对应关系的常量,可以提高代码的可读性和可维护性。使用枚举可以避免使用魔法数,并且使代码更加易读和清晰。

四、位段

1.什么是位段?

在C语言中,位段(bit-field)是一种数据结构,可用于指定特定长度的位序列,以用于存储和访问字段。

在结构体或联合体的定义中,可以使用位段来定义成员。位段使用关键字unsigned intsigned intint来指定成员的数据类型,然后使用冒号:来指定该成员所占据的位数。

2.位段的使用

struct Flags {
    unsigned int isImportant : 1;
    unsigned int isEnabled : 1;
    unsigned int isReady : 1;
};

在这个示例中,定义了一个名为 Flags 的结构体,其中包含了三个位段成员:isImportant、isEnabled 和 isReady。每个位段成员都使用了unsigned int数据类型,并用冒号:指定了它们所占据的位数。

使用位段可以有效地管理和存储只需要使用特定位数的数据。它们在节省内存空间方面非常有用,尤其在需要对一些开关标志进行存储和访问时。在上述示例中,每个成员只占据一个位,因此在一个字节中可以存储8个标志位。

3.位段的访问

 可以使用点.运算符来访问结构体中的位段成员,就像访问其他结构体成员一样。例如,可以通过以下方式设置和访问位段成员的值:

struct Flags flags;
flags.isImportant = 1;
flags.isEnabled = 0;
flags.isReady = 1;

if (flags.isImportant) {
    printf("This is important.\n");
}

在这个例子中,可以设置和访问位段成员的值,以及使用条件语句根据它们的值执行相应的操作。

需要注意的是,对位段成员的操作可能受限于编译器的实现和CPU的存储结构。具体的位段长度、字节对齐以及符号类型等因素可能会有所不同。因此,在使用位段时需要了解相关编译器和系统的特性和限制。

五、总结

本文介绍了C语言中的四个重要知识点:结构体、联合体、枚举和位段。结构体是用于描述复杂数据类型的一种机制,可以定义包含多个成员的数据类型。联合体是一种特殊的数据类型,允许在同一内存空间中存储不同类型的数据。枚举是一种用户自定义的数据类型,用于定义一组具有离散取值的常量。位段是一种数据结构,可用于指定特定长度的位序列,以用于存储和访问字段。最后感谢各位大佬的阅读!

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值