一、使用场景及概念
简单的float、int、double等类型无法描述一个复杂对象,比如如果要描述一本书,需要有书名、作者、价格……而这个的实现,仅仅靠一个类型是无法实现的
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,用来描述复杂对象
二、结构体的使用
1.结构的声明
- 结构的声明不是一定要放在main函数外面的,只不过创建的一般是想要全局效果的,所以放在外面
- 成员列表里面可以是变量、数组、指针、甚至是其他结构体
struct tag //tag---标签名
{
member-list //成员列表
}varible-list //变量列表
struct stu
{
char name[20];
char number[20];
double score;
}; //变量列表这边是创建变量的一种方法,可以省略
2.结构体变量的创建
第一种-------在声明类型的同时定义变量,起的是全局的效果
struct stu
{
char name[20];
char number[20];
double score;
}s3, s4;
第二种------定义结构体变量,起的是局部的效果
>int main()
{
struct stu s1 = {"小明","22105310",100};
return 0;
}
2.结构体变量的初始化
struct S
{
int a;
char c;
};
struct P
{
double d;
struct S s;
float f;
};
int main()
{
struct P p = { 5.5, {100, 'b'}, 3.14f }; //嵌套初始化
struct S a = {1,'c'}; //初始化
}
3.结构体成员的访问
第一种-------结构体.成员名
int main()
{
struct stu s1 = {"小明","22105310",100};
struct stu s2 = { "小红","22105311",99 };
printf("%s %s %.2lf\n", s1.name, s1.number, s1.score);
printf("%s %s %.2lf\n", s2.name, s2.number, s2.score);
print(&s1);
return 0;
}
第二种-----结构体指针->成员名
void print(struct stu* s1)
{
printf("%s %s %.2lf\n", s1->name, s1->number, s1->score);
}
int main()
{
struct stu s1 = {"小明","22105310",100};
print(&s1);
}
4.结构体的传参
struct S
{
int a;
char c;
};
struct P
{
double d;
struct S s;
float f;
};
void Print1(struct P sp) //结构体传参
{
//结构体变量.成员
printf("%lf %d %c %f\n", sp.d, sp.s.a, sp.s.c, sp.f);
}
void Print2(struct P* p1) //传结构体的地址
{
printf("%lf %d %c %f\n", (*p1).d, (*p1).s.a, (*p1).s.c, (*p1).f);
//结构体指针->成员
printf("%lf %d %c %f\n", p1->d, p1->s.a, p1->s.c, p1->f); //嵌套访问
}
int main()
{
struct P p = { 5.5, {100, 'b'}, 3.14f };
scanf("%d %c", &(p.s.a), &(p.s.c));
printf("%lf %d %c %f\n", p.d, p.s.a, p.s.c, p.f); //嵌套访问
Print1(p);//传值调用
Print2(&p);//传址调用
return 0;
}
结构体传参的时候,最好传结构体的地址,不仅可以修改实参,而且函数传参的时候,参数是需要压栈的,如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大。会导致性能的下降