(初阶结构体struct详解)一学就废

前言

大家有没有想过为什么会出现结构体这个东西呢,原因是我们生活中有很多复杂的对象,比如说一个人,一本书,不能用一个简单数字就描述清楚。结构体由一组不同的类型的成员组合而成,通常用来表示类型不同但是又相关的若干数据,结构体类型不是由系统定义好的,而是需要程序设计者自己定义的。
结构体与数组不同 数组是一组相同类型元素的集合
而结构体是由一组不同类型元素组成的

结构体的声明

自定义数据类型strcut后面可以加合适的标签名

struct tag //结构体声明,strcut后可以自定义合适的标签名
{
	//....
	//成员列表
};

结构体类型的声明

结构体成员的类型可以是变量、数组、指针、甚至是其他结构体

例如一个学生:


 struct Stu 
{
	char name[20];//名字
	short age;//年龄
	char sex[5];//性别
	int id;//学号
}//分号不能丢

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

有了结构体的类型,那如何定义变量呢?
struct Stu 相当于int, float…
s1 相当于我们的变量名

struct Stu
{
	char name[20];//名字
	short age;//年龄
	char sex[5];//性别
	int id;//学号
};
struct Stu s2;//全局变量
int main()
{
	struct Stu s1;//结构体变量的定义
	return 0;
}

那么如何初始化呢

struct Stu
{
	char name[20];//名字
	short age;//年龄
	char sex[5];//性别
	int id;//学号
};

int main()
{
	struct Stu s1 = {"William", 21, "male", 386910};
	return 0;
}

结构体成员的访问

初始化完,我们如何访问呢,这里我们需要(.)操作符进行访问
(.)后面加成员名

struct Stu
{
	char name[20];//名字
	short age;//年龄
	char sex[5];//性别
	int id;//学号
};

int main()
{
	struct Stu s1 = {"William", 21, "male", 386910};
	printf("name=%s, age=%hd, sex=%s, id=%d\n", s1.name, s1.age, s1.sex, s1.id);
	return 0;
}

运行结果:
在这里插入图片描述

上面说到结构体中不仅由整形变量,浮点型,字符,也可以有结构体
我们又创建了一个struct P,成员是int类型和char类型
接着我们把struct P放到struct Stu里,结构体嵌套结构体

struct P
{
	int n;
	char ch;
};

struct Stu
{
	char name[20];
	short age;
	char sex[5];
	int id;
	struct P p;
};

int main()
{
	struct Stu s1 = { "William", 21, "male", 386910, {11, 'C'}};//结构体嵌套结构体也需要使用大括号
	printf("%d, %c\n", s1.p.n, s1.p.ch);//只打印struct P里面的成员
	return 0;//需要先s1.找到Stu里的成员,再.p找到P里面的成员,再.找到对应的成员
}

运行结果:
***********可想而知,这就不放图了

结构体传参

我们写一个Print打印函数把s1传过去,我们用s2接收,然后打印结构体成员

传值调用:

struct Stu
{
	char name[20];
	short age;
	char sex[5];
	int id;
};

void Print(struct Stu s2)
{
	printf("%s, %hd, %s, %d\n", s2.name, s2.age, s2.sex, s2.id);
}

int main()
{
	struct Stu s1 = { "William", 21, "male", 386910};
	Print(s1);//传值调用
	return 0;
}

传址调用:

我们把s1的地址传过去,用指针接收,理所应当打印的时候需要用解引用(*)操作符
我们也可以用(->)箭头指向要打印的成员

struct Stu
{
	char name[20];
	short age;
	char sex[5];
	int id;
};

void Print(struct Stu* s2)
{	//结构体变量.成员
	printf("%s, %hd, %s, %d\n", (*s2).name, (*s2).age, (*s2).sex, (*s2).id);
	//结构体变量->成员
	printf("%s, %hd, %s, %d\n", s2->name, s2->age, s2->sex, s2->id);
	//两种打印方式效果相同
}

int main()
{
	struct Stu s1 = { "William", 21, "male", 386910};
	Print(&s1);//传址调用
	return 0;
}

问:上面两种方式哪个好些?
答案是:传址调用

总结:
函数传值过去要压栈,需要再copy一份结构体,如果结构体比较大,数据比较多,内存压力就会比较大,导致性能下降

传址过去是直接把地址交给指针变量,一个指针大小无非是4/8个字节

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不会敲代码的小张:)

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

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

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

打赏作者

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

抵扣说明:

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

余额充值