目录
一、结构体的声明
1、结构的基础知识
2、结构的声明
3、结构成员的类型
4、结构体变量的定义和初始化
二、结构体成员的访问
1、点操作符访问
2、->操作符访问
3、解引用访问
三、结构体嵌套
四、结构体传参
1、传值调用
2、传址调用
一、结构体的声明
1、结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。
2、结构的声明
struct xx //这一整串是类型
{
char name[20];
int age; //代码块里是结构体成员
double money; //可以是不同类型
}list; //list - 结构体变量
//注意:后面有 ; 号
通过上面的模板来举个例子
假设要描述一名学生(名字、年龄、分数)
struct student //类型
{
//结构体成员
char name[20];
int age;
double score;
}stu,stu2; // stu、stu2 - 也是结构体变量(全局变量)
int main()
{
//创建结构体变量(局部变量) 类型 + 变量
struct student stu1;
}
3、结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
4、结构体变量的定义和初始化
struct student //类型
{
char name[20];
char sex[10];
int age;
double score;
}stu,stu2;
int main()
{
//结构体变量初始化
struct student stu1 = { "小明","男",18,72.5 };
struct student stu2 = { "小红","女",18,96.7 };
}
二、结构体成员的访问
这其实在以往博客也讲过了 -> 点我!速看
1、变量 . 成员
#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 stu2 = { "小红","女",18,96.7 };
//结构体访问
printf("名字:%s\n年龄:%d\n性别:%s\n分数:%.1lf\n", stu1.name, stu1.age, stu1.sex, stu1.score);
return 0;
}
程序运行结果:
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;
}
程序运行结果:
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()
{
struct P p = { 5.5,{100,'s'},33.3 };
//只打印嵌套的结构体
printf("%d %c\n", p.s.a, p.s.c);
return 0;
}
程序运行结果:
只要一步一步去访问,嵌套结构体同样也能访问。当然也可以用指针来访问,这里就不为大家演示了。
四、结构体传参
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;
}
程序运行结果:
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);
}
int main()
{
struct student stu1 = { "小明",18,"男",95.5 };
//封装一个Print函数负责打印
Print(&stu1);
return 0;
}
同样也能用 -> 操作符来访问,这里就不演示了
程序运行结果:
那么大家认为传值调用好还是传址调用好呢?
答案是传址调用,因为传址调用时,形参也有自己独立的空间,把实参传递给形参就要消耗时间,这时传参的压力就比较大。如果是传址调用,因为一个地址的大小无非就是4或者8个字节,形参用指针变量接收,压力也相对较小些。
官方说法:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。