前言
欢迎来到浩克讲c语言,今天我们来讲结构体,满满的干货奥!
一、结构体类型的说明
1.1结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
1.2结构的声明
struct tag
{
member-list;
}variable-list;
例如描述一个学生:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[8];//性别
}s1,s2;
//s1,s2是通过 struct Stu类型创建的变量
//s1,s2是全局变量
struct Stu s3;//这样创建结构体变量也是可以的
如果你觉得struct Stu在定义变量时比较麻烦,你也可以使用 typedef 进行重定义,例如:
typedef struct Stu
{
char name[20];//名字
int age;//年龄
char sex[8];//性别
}stu;
stu s1;//这样就可以创建一个结构体变量了
1.3 结构成员的类型
结构的成员可以是标量,数组,指针,甚至是其他结构体。
二、结构体初始化
那么结构体如何初始化呢?先举个简单的例子
struct point
{
int x;
int y;
};
int main()
{
struct point p1={10,20};//用大括号将初始化的内容括起来。
return 0;
}
如果遇到结构体里有多种类型,就类比多维数组的初始化。
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
return 0;
}
三、结构体成员访问
首先给大家介绍两个结构成员访问操作符 第一个. 第二个-> 。
.在使用时 : 结构体变量.结构体成员。
->在使用时:结构体指针->结构体成员。
例如:
.的使用
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
printf("%d\n", sp.x);//5
printf("%d %d\n", sp.p.x, sp.p.y);//10 20
printf("%lf\n", sp.z);//5.500000
printf("%s\n", sp.arr);//hello
return 0;
}
或者
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
void print(struct s ss)
{
printf("%d\n", ss.x);//5
printf("%d %d\n", ss.p.x, ss.p.y);//10 20
printf("%lf\n", ss.z);//5.500000
printf("%s\n", ss.arr);//hello
}
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
print(sp);
return 0;
}
->的使用
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
void print(struct s* ss)
{
printf("%d\n", ss->x );//5
printf("%d %d\n", ss->p.x, ss->p.y);//10 20
printf("%lf\n", ss->z);//5.500000
printf("%s\n", ss->arr);//hello
}
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
print(&sp);//将sp的地址传过去
return 0;
}
当然除了打印也可以修改结构体里的值
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
void print(struct s* ss)
{
ss->x = 10;
ss->p.x = 100;
ss->p.y = 200;
ss->z = 6.0;
strcpy(ss->arr, "world");//这里要注意arr是数组首地址,不能直接修改,所以用strcpy
printf("%d\n", ss->x);//10
printf("%d %d\n", ss->p.x, ss->p.y);//100 200
printf("%lf\n", ss->z);//6.000000
printf("%s\n", ss->arr);//world
}
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
print(&sp);
return 0;
}
四、结构体传参
两种形式:传值,传址。
#include<stdio.h>
struct point
{
int x;
int y;
};
struct s
{
int x;
struct point p;
double z;
char arr[20];
};
void print1(struct s sss)
{
printf("%d\n", sss.x);
printf("%d %d\n", sss.p.x, sss.p.y);
printf("%lf\n", sss.z);
printf("%s\n", sss.arr);
}
void print2(struct s* ss)
{
printf("%d\n", ss->x);
printf("%d %d\n", ss->p.x, ss->p.y);
printf("%lf\n", ss->z);
printf("%s\n", ss->arr);
}
int main()
{
struct s sp = { 5,{10,20},5.5,"hello" };
print1(sp);
print2(&sp);
return 0;
}
在这里给大家提一个问题 上面 print1 和 print2 哪个好一些?
答案是:首选 print2 函数。
原因是:函数在传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
结论:
结构体在传参的时候要传递结构体的地址。
总结
如果觉得浩克可以的话,记得给个关注奥,我们一起努力!