C语言自定义变量类型——结构体详解


前言

关于C语言,在指针学习过程中,在学习之余,做了一次总结,写成了一篇详解博客,也向大家分享的我对于指针的见解,我发现将所学的内容写成博客,不仅仅可以使和我一样的初学者们更快的了解相关知识点,还可以让我查缺补漏,弥补自己的短板,让我的基础更加扎实,所以在学完结构体以后,我也将结构体的内容整理成一篇博客,向大家分享。

为什么要学习结构体

当我们需要表达一个数据的时候,我们就需要用到变量,而变量又需要定义一个类型。我们通过之前的学习,知道了C语言中变量类型有:int、double、char、float等等基础类型,还有指针等等。但是如果我们想表达的数据比较复杂,不是一个数据,例如:日期(年、月、日)、学生信息(姓名、性别、年龄等等)、时间(时、分、秒)等等。而我们又想用一个整体来表达这些所有的数据,这个时候我们就需要用到一个自定义变量类型——结构体。

什么是结构体

结构体是C语言中一种重要的数据类型,该数据类型由一组称为成员(或称为域,或称为元素)的不同数据组成,其中每个成员可以具有不同的类型。结构体通常用来表示类型不同但是又相关的若干数据。

注意:结构体是一种数据类型!!!

一、结构体:struct

1、结构体类型的声明

(1)结构体的基础知识

成员变量:结构是一些值的集合,这些值称为成员变量。

结构体的每个成员可以是不同类型的变量。

(2)结构体的声明

结构体的定义如下所示,struct为结构体关键字,tag为结构体的标志,member-list为结构体成员列表,其必须列出其所有成员;variable-list为此结构体声明的变量。

struct tag 
{
   
   
	member-list
}variable-list;

例1:描述一个学生信息

#include<stdio.h>
//声明一个结构体类型
//声明一个学生类型,是想通过学生类型来创建学生变量(对象)
//描述学生:属性·名字+电话+性别+年龄
struct Stu
{
   
   
	char name[20];//名字
	char tele[12];//电话
	char sex[5];//性别
	int age;//年龄
}s4,s5,s6;//分号不能丢

struct Stu s3;//s3,s4,s5,s6为全局变量
int main()
{
   
   
	//创建结构体变量
	struct Stu s1;
	struct Stu s2;
	//s1,s2为局部变量
	return 0;
}

易错提示:
一定不要忘记结束时的分号!!!

(3)特殊的声明

在声明结构的时候,可以不完全的声明
例2:匿名结构体类型

#include<stdio.h>
struct
{
   
   
	int a;
	char b;
	float c;
}x;

struct
{
   
   
	int a;
	char b;
	float c;
}* p;

int main()
{
   
   
	p = &x;//错误 E0513	不能将 "struct <unnamed> *" 类型的值分配到 "struct <unnamed> *" 类型的实体	

	return 0;
}

上面的两个结构在声明的时候省略了结构体的标志(tag)。(是正确的)

上述代码的问题出现在:p = &x。//这是非法的。
上面的两个匿名结构体虽然各自的成员是一模一样的,但是在编译器看来,它们是两个不同的类型,所以出现了报错(部分编译器是警告)。

2、结构体的自引用

结构体的自引用就是指在结构体内部,包含指向自身类型结构体的指针。

在之前的学习中,我们知道了在函数中可以包含自己(即递归),那么在结构中包含一个类型为该结构体本身的成员是否可以呢?

例3:

#include<stdio.h>
struct Node
{
   
   
	int data;//4
	struct Node n;//4+套娃
};

int main()
{
   
   
	sizeof(struct Node);
	return 0;
}

运行结果:
错误 C2460 “Node::n”: 使用正在定义的“Node”

这是为什么呢?因为n定义中又有n,无限循环,系统无法确定该结构体的长度,会判定定义非法。

切记,结构体自引用,成员定义只能是指针。

例4:正确的自引用

#include<stdio.h>
struct Node
{
   
   
	int data;//4
	struct Node* n;//4/8
};

int main()
{
   
   
	int a = sizeof(struct Node);
	printf("%d", a);
	return 0;
}

运行结果为:8(因为博主是32位)

这是为什么呢?因为我们在自引用时把结构的成员定义为指针,又指针的长度是确定的(上一节指针详解中提到过),所以此时结构体的长度也是确定的。

这时候可能有人又有疑问了,我们刚刚学了一种特殊的声明方式——匿名,那在自引用的时候,我们可不可以使用匿名了,就拿例4来举例子,因为这时候,我们使用了匿名结构,所以里边使用“Node* n;”不就好了吗?我们来看看,结构是怎样的:
例5:

#include<stdio.h>
struct
{
   
   
	int data;
	Node* n;
}Node;

int main()
{
   
   
	int a = sizeof(struct Node);
	printf("%d", a);
	return 0;
}

运行结果为:一大堆报错

这是为什么呢?因为我们在声明结构体的内部,就使用了Node这个变量,但是我们的编译器是在声

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WE-ubytt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值