c语言 结构体声明和引用、,结构体的声明与自引用

本文介绍了C语言中结构体自引用的概念,通过实例展示了如何正确使用结构标签和typedef进行声明,重点讲解了链表结构中自引用的作用以及为何使用指针。同时,讨论了结构体嵌套和typedef技巧在避免无限嵌套中的应用。
摘要由CSDN通过智能技术生成

今天上了数据结构课程的第一堂课,经常会看到下面这种语法:结构体有个成员变量是指向该结构体的指针,也就是自引用(self reference)。翻看了下一章节内容,才知道这是链表的结构基础。平时C语言用的比较少,借此机会重新复习了下结构体,在此记录相关知识。

结构体的声明

我们在定义结构体时,常常会用到两种方式。

方式1. 使用结构标签

用标签变量赋予结构体一个名字,这样定义结构体之后,可以用标签来声明结构体变量。

/*

**标签(tag)为成员列表提供一个名字,可以在后续的声明中使用

**下面这个声明,将标签PEOPLE与成员列表联系在一起(也就是定义了一个名为PEOPLE的结构体),

**并声明了名为Man与Women的两个结构体变量

*/

struct PEOPLE{

int a;

char b;

float c;

}Man,Women;//这里是声明的同时创建了两个变量。

/*

** 变量的声明

** 声明变量时,需要在标签名前加上关键字struct

*/

struct PEOPLE Boy,Girl;//声明了结构体变量 Boy 与 Girl

注意:声明结构体变量时一定要在前面加上struct关键字。但这样难免有些繁琐,所以大家都喜欢用下面介绍的方式2

方式2. 利用typedef技巧

/*

**typedef用于定义一个新的类型名,可以认为是为结构体起一个别名

**此段代码将原来的 struct PEOPLE 重新定义为类型people

*/

typedef struct PEOPLE{

int a;

char b;

float c;

}people;

/*

**变量的声明

*/

people Women,Girl; //声明了结构体变量 Women 与 Girl;

people Boy[20]; //声明了元素类型为结构体people的数组 Boy

可以看到,用typedef定义结构体后,结构体变量的声明变得十分方便。

结构体的自引用

结构体的自引用(self reference),就是在结构体内部,包含指向自身类型结构体的指针。这是实现链表结构的基础。

我们知道,顺序表的数据元素依次存放于一组地址连续的存储单元。而链表是用一组任意的存储单元来存放元素的,这些存储单元可以零散分布在内存的任何位置,大大提高存储器的使用效率。那么问题来了,既然存储单元地址不是连续的,那么前一个节点如何知道下一个节点的地址呢?这里就用到了结构体的自引用。在前一个节点(一个结构体变量)的成员变量中,把那个指针定义为下一个节点的地址,这样层层连接,实现了链表的存储。

但是,为什么定义结构体时,该成员变量是一个指针,而不直接声明该结构体自己呢?

https://blog.csdn.net/gzbaishabi/article/details/34926699

请看这篇文章,表述的非常好。

下面仍旧以两种结构体声明方式,分开讨论

方式1. 使用结构标签

错误的方式

/*

**下面这种声明是错误的。

**PEOPLE是一个结构体,成员变量b的仍旧是结构体

**在分配内存时,由于无限嵌套,编译器无法确定PEOPLE的长度

*/

struct PEOPLE{

int a;

struct PEOPLE b;

};//非法

正确的方式

/*

**由于指针的长度是确定的(指针长度为4),所以编译器能够确定该结构体的长度

*/

struct PEOPLE{

int a;

struct PEOPLE *b;

};

方式2. 使用typedef

错误的方式

/*

**下面这种声明是错误的。

**使用typedef时,程序执行到该段结束才完成了类型PEOPLE的定义

**因此,虽然这里用了指针,但还是错误,因为还没完成类型的定义

*/

typedef struct{

int a;

struct people *b;

}people;//非法

正确的方式

/*

**利用结构标签进行指针的声明

*/

typedef struct tag{

int a;

struct tag *b;

}people;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值