👦个人主页:Weraphael
✍🏻作者简介:目前正在回炉重造C语言(2023暑假)
✈️专栏:【C语言航路】
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍
目录
- 一、结构体的声明
- 1.1 结构的概念
- 1.2 结构的定义
- 1.3 结构成员的类型
- 1.4 结构体变量的初始化
- 二、结构体成员的访问
- 2.1 变量 . 成员
- 2.2 指针变量 -> 成员
- 2.3 解引用访问
- 三、结构体嵌套
- 四、结构体传参
- 4.1 传值调用
- 4.2 传址调用
- 4.3 传值调用和传值调用的区别
一、结构体的声明
1.1 结构的概念
结构是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。
1.2 结构的定义
结构体是用来描述复杂对象的
// tag - 是标签名,是可以根据需求改变的
struct tag //这一整串是类型
{
//代码块里是结构体成员
//可以是不同类型
member_list // 成员列表
}list;
//list - 结构体变量
//注意:后面有分号
通过上面的模板来举个例子
假设要描述一名学生(名字、年龄、分数)
struct student //类型
{
//结构体成员
char name[20];
int age;
double score;
}stu,stu2;
// stu、stu2 - 也是结构体变量(全局变量)
int main()
{
// 创建结构体变量(局部变量)
// 类型 + 变量
struct student stu1;
return 0;
}
1.3 结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
1.4 结构体变量的初始化
struct student //类型
{
char name[20];
char sex[10];
int age;
double score;
};
int main()
{
//结构体变量初始化
struct student stu1 = { "小明","男",18,72.5 };
return 0;
}
二、结构体成员的访问
往期博客链接:点击传送
2.1 变量 . 成员
#include <stdio.h>
struct student //类型
{
char name[20];
int age;
char sex[10];
double score;
};
int main()
{
//结构体变量初始化
struct student stu1 = { "小明",18,"男",95.5 };
//结构体访问
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", stu1.name, stu1.age, stu1.sex, stu1.score);
return 0;
}
【程序结果】
2.2 指针变量 -> 成员
#include <stdio.h>
struct student //类型
{
char name[20];
int age;
char sex[10];
double score;
};
int main()
{
//结构体变量初始化
struct student stu1 = { "小明",18,"男",95.5 };
struct student* pa = &stu1;
//结构体访问
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", pa->name,pa->age,pa->sex,pa->score);
return 0;
}
【程序结果】
2.3 解引用访问
#include <stdio.h>
struct student //类型
{
char name[20];
int age;
char sex[10];
double score;
};
int main()
{
//结构体变量初始化
struct student stu1 = { "小明",18,"男",95.5 };
struct student* pa = &stu1;
//结构体访问
//*pa就是stu1
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n",(*pa).name,(*pa).age,(*pa).sex,(*pa).score);
return 0;
}
【程序结果】
三、结构体嵌套
#include <stdio.h>
struct S
{
int a;
char c;
};
struct P
{
double d;
struct S s;
double f;
};
int main()
{
//100和's'是结构体s的
struct P p = { 5.5,{100,'s'},33.3 };
//只打印嵌套的结构体
printf("%d %c\n", p.s.a, p.s.c);
return 0;
}
【程序结果】
只要一步一步去访问,嵌套结构体同样也能访问。当然也可以用指针来访问,这里就不为大家演示了。
四、结构体传参
4.1 传值调用
注意:如果使用传值调用,形参的改变不影响实参。
#include <stdio.h>
struct student
{
char name[20];
int age;
char sex[6];
double score;
};
//不需要返回参数用void
void Print(struct student stu) //传结构体变量同样也能用结构体变量来接收
{
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", stu.name, stu.age, stu.sex, stu.score);
}
int main()
{
struct student stu1 = { "小明",18,"男",95.5 };
//封装一个Print函数负责打印
Print(stu1);
return 0;
}
【程序结果】
4.2 传址调用
#include <stdio.h>
struct student
{
char name[20];
int age;
char sex[6];
double score;
};
//不需要返回参数用void
void Print(struct student* stu) //传地址需要用指针来接收
{
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", (*stu).name, (*stu).age, (*stu).sex, (*stu).score);
// 或者还可以使用->操作符来访问
//printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", stu->name, stu->age, stu->sex, stu->score);
}
int main()
{
struct student stu1 = { "小明",18,"男",95.5 };
//封装一个Print函数负责打印
Print(&stu1);
return 0;
}
【程序结果】
4.3 传值调用和传值调用的区别
那么大家认为传值调用好还是传址调用好呢?
答案是:传址调用
- 因为传址调用时,形参也有自己独立的空间,把实参传递(拷贝)给形参就要消耗时间,这时传参的压力就比较大。如果是传址调用,因为一个地址的大小无非就是4/8个字节,形参用指针变量接收,压力也相对较小些。
- 官方说法:函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。