结构体是什么?怎么使用?

结构体

在现实世界中,我们是如何处理名字和身高等信息的?加入我们需要汇总学生的体检信息,我们会将学生的姓名、性别、年龄、身高、体重等分别进行建表吗?显然这是不可能的,不说分别建设多张表的麻烦性,就算建好了,等进行调用查询时,也是一件麻烦的事情。通常是一个人一行数据,包含了所有信息。一个班所有的同学即为一个集合。
同一种类型的数据的集合是数组,和数组不同,结构体是多种类型的数据的集合。

一. 声明与创建

1. 结构体声明

如果我们需要统计体检信息,我们会用到以下类型:

  • char 类型的姓名
  • int 类型的身高
  • float 类型的体重
    对以上数据进行结构体声明如下:
struct student
{
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
};

其中student结构名
name、height、weight结构体成员

对上述代码可以简单说明为:将三个数据集中起来生成struct student类型。也就是说这是数据类型的声明,而并没有定义对象(变量)的实体。声明之后,就相当于C语言库中的int、double等类型创建int型变量一样,可以创建struct student类型的结构体变量。
如果映像现实,就如下图,生成一个框架,然后在进行打印,然后发给学生,让学生填写。

2. 结构体成员的类型

结构体成员可以是标量、数组、指针,甚至可以是其他结构体。

3.结构体变量的定义与初始化

(1). 定义

在之前,我们使用int、doule等类型进行创建变量时是这样操作的:int a;,而结构体类型进行创建变量也是如此。当我们已经进行好结构体声明之后,就可以进行结构体变量的创建。

  1. 方法一:声明结构体的同时创建结构体变量
struct student
{
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
}stu1,stu2;

其中stu1stu2即为struct studen类型的变量。

2.方法二:先声明,再创建

struct student
{
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
};

struct student stu1;
struct student stu2;

其中stu1stu2即为struct studen类型的变量。

(2). 初始化

生成变量的时候要进行初始化,我们在创建变量的时候,最好同时进行初始化。

  1. 方法一:声明结构体的同时创建结构体变量并且进行初始化
struct student
{
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
}stu1{"zhangsan",185,90.0};
  1. 方法二:
struct student
{
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
};

struct student stu1 = {"zhangsan",185,90.0};

二. 访问结构体成员

当我们声明一个结构体类型之后,使用这个结构体类型创建一个变量,这个结构体类型中有几个成员,这个结构体变量所对应的就有几个成员。例如以下代码:

struct student
{
	//结构体成员
	char name[32];  //姓名
	int height;     //身高
	float weight;   //体重
};

struct student stu1 = {"zhangsan",185,90.0};

上图:

而如果想通过创建的这个stu1变量访问其中的成员,就需要使用到.->操作符。

1. .操作符(结构体变变量访问成员)

.操作符a.b表示结构体a的成员b

我们可以看到stu1中的成员有:nameheightweight
我们可以依靠.操作符,使用结构体变量访问成员。

	struct student stu1 = { "zhangsan",185,90.0 };

	stu1.weight = 70.0;

	printf("name: %s\n", stu1.name);
	printf("height: %d\n", stu1.height);
	printf("weight: %.1f\n", stu1.weight);

输出为:

	name: zhangsan
	height: 185
	weight: 70.0

2. ->操作符(结构体指针访问指向变量的成员)

->操作符a->b用指针访问结构体a中的成员b

我们可以通过结构体变量来访问指针,而有时候我们得到的不是结构体变量,而是一个指向结构体变量的指针。

void my_print(struct student* ps)
{
	printf("name: = %s\n", (*ps).name);
	//ps为一个指针变量,里面存储的是stu1的地址,通过地址可以直接找到stu1,然后再通过.操作符找到成员。

	printf("name: = %s\n", ps->name);
	//通过指针找到结构体变量,然后再通过.操作符找到成员,这种方式比较繁琐,而使用->操作符就比较简洁了。
}

int main()
{
	struct student stu1 = { "zhangsan",185,90.0 };
	
	my_print(&stu1);

	return 0;
}

输出为:

	name: = zhangsan
	name: = zhangsan

三. 结构体传参

我们知道,函数传参的方式分为值传参和址传参,在结构体进行传参时,我们应该首选哪种传参方式呢?

void my_print1(struct student s)
{
	//结构体传参
	printf("name: = %s\n", s.name);
}

void my_print2(struct student* ps)
{
	//结构体地址传参
	printf("name: = %s\n", ps->name);
}

int main()
{
	struct student stu1 = { "zhangsan",185,90.0 };

	my_print1(stu1);
	my_print2(&stu1);

	return 0;
}

上述代码中的两种传参方式都可以进行传参,并且都可以输出想要的结果。但是在实际使用过程中,地址传参的方法是优于,结构体传参的。

因为在函数进行传参时,参数是需要压栈的,如果使用值传递,在传递一个结构体时,结构体过大,参数压栈的系统开销比较大,所以会导致性能下降。简单来说就是值传递,会创建一个临时拷贝,这个临时拷贝也会在内存中分配一块新的内存空间,如果需要拷贝的数据比较多,那么无疑这种方式会造成极大的浪费。

结构体传参时,要传递结构体变量的地址。

际使用过程中,地址传参的方法是优于,结构体传参的。

因为在函数进行传参时,参数是需要压栈的,如果使用值传递,在传递一个结构体时,结构体过大,参数压栈的系统开销比较大,所以会导致性能下降。简单来说就是值传递,会创建一个临时拷贝,这个临时拷贝也会在内存中分配一块新的内存空间,如果需要拷贝的数据比较多,那么无疑这种方式会造成极大的浪费。

结构体传参时,要传递结构体变量的地址。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

排骨炖粉条

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

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

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

打赏作者

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

抵扣说明:

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

余额充值