请回答c语言-结构体【入门】


思维导图

1. 结构体的声明

1.1 结构的基础知识

生活中我们见到的对象都是复杂的对象,比如说描述一只猫或是一本书,不肯能用简单的型或是浮点型来描述这些类型

1.2 结构的声明

struct tag
{
member-list;
}variable-list;

假如说我要描述一个pokemon

我需要从多种特性来描述,比如名字,图鉴编号,身高或是体重

第一种创建方式
struct Pokemon
{
	char name[20];//名字
	int id;//图鉴编号
	float height; //身高
	float weight;//重量
	char fighting_type[20]; //属性
	char species[15]; //类型
};
int main()
{
	struct Pokemon pikachu;//拿这个结构体来创建一个变量,变量类型是这个结构体Pokemon
    return 0;
}
第二种创建方式
struct Pokemon
{
	char name[20];//名字
	int id;//图鉴编号
	float height; //身高
	float weight;//重量
	char fighting_type[20]; //属性
	char species[15]; //类型
}pokemon1,pokemon2;//全局

这两种创建方式的区别是第二种创建方式创建的结构体变量是全局

1.3 结构成员的类型

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

1.4 结构体变量的定义和初始化

和数组一样,结构体也要初始化,按照之前定义的顺序和类型定义

struct Pokemon pikachu = { "Pikachu",25,0.4,6.0,"electric","mouse pokemon" };

2. 结构体成员的访问

之前都已经写过,就不细写了

  • 结构体变量访问成员

结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数。

struct S s;
strcpy(s.name, "zhangsan");//使用.访问name成员
s.age = 20;//使用.访问age成员

或是输出

printf("name = %s id = %d height = %.1f weight = %.1f\n", pikachu.name, pikachu.id, pikachu.height, pikachu.weight);

image-20211119102925643

  • 结构体指针访问指向变量的成员

有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针(->)。

struct Pokemon* ps = &pikachu;//结构体指针
	printf("name = %s id = %d height = %.1f weight = %.1f\n", ps->name, ps->id, ps->height, ps->weight);
	printf("name = %s id = %d height = %.1f weight = %.1f\n", (*ps).name, (*ps).id, (*ps).height, (*ps).weight);

3. 结构体传参

在我们需要传参来打印数组的时候,我们选择那一种Print函数会好一点呢

struct S
{
	int arr[1000];
	float f;
	char ch[100];
};

void print1(struct S tmp)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", tmp.arr[i]);
	}
	printf("\n");
	printf("%f\n", tmp.f);
	printf("%s\n", tmp.ch);
}

void print2(struct S* ps)
{
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
	printf("%f\n", ps->f);
	printf("%s\n", ps->ch);
}
int main()
{
	struct S s = { {1,2,3,4,5,6,7,8,9,10}, 5.5f, "Hello there" };
	print1(s);
	print2(&s); 
	return 0;
}

print1是一个值传参,所以会创造一种临时拷贝,但是再次重新创造一个空间的话,就会造成空间的浪费,倘若结构体里面所含的内容足够大的话,那么将导致问题出现

image-20211119110724396

print2就是传地址,所以是不用创建一整个结构体,只是创造一个指针,当结构体足够大的时候,节省空间的效率就会非常高。

下面是比较专业的解释:

  • 函数传参的时候,参数是需要压栈的。
    如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。

当程序运行的时候,函数的栈的过程是

比如执行这样一段代码

int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}

int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);
	printf("%d\n", c);
	return 0;
}

程序执行的过程是按照主函数的代码顺序在栈中从下到上,从先到后的创建
image-20211119111552309

小结:

一般我们在传参结构体的时候采用传地址的话是一个较好的选择

总结

老铁们有收获的话一定要给个赞,多多评论哦

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

言之命至9012

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

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

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

打赏作者

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

抵扣说明:

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

余额充值