结构体的声明
基础知识:
数组:一组相同类型元素的集合
结构体:也是一些值的集合,但是值的类型可以不同。
结构的成员可以是标量、数组、指针,甚至是其他结构体。
结构体在创建的时候实际上是创建了结构体类型
使用实例:
struct B
{
char c;
short s;
double d;
};//分号不能丢
struct Stu//创建结构体类型
{
//成员变量
struct B sb;
char name[20];
int age;
char id[20];
}s1, s2;//声明类型的同时定义s1和s2也是结构体变量,同时因为定义在花括号外,所以是全局变量
int main()
{
struct Stu s = { {'w',20,3.14},"张三",18,"20200543 " };//结构体嵌套初始化
return 0;
}
结构体成员的访问
结构变量的成员是通过点操作符(.)访问的。
结构体指针访问指向变量的成员用->访问
续上面的代码
printf("%c\n",s.sb.c);//点操作符访问
printf("%s\n",s.id);
struct Stu* ps=&s;//定义指针变量
printf("%c\n",(*ps).sb.c);//解引用的访问访问
printf("%c\n",ps->sb.c);//sb不是指针,所以只能用.来访问
结构体传参
直接上代码:
struct B
{
char c;
short s;
double d;
};
struct Stu
{
//成员变量
struct B sb;
char name[20];
int age;
char id[20];
};
void print1(struct Stu t )
{
printf("%c %d %lf %s %d %s", t.sb.c, t.sb.s,t.sb.d,t.name,t.age,t.id);
}
void print2(struct Stu* ps)
{
printf("%c %d %lf %s %d %s", ps->sb.c,ps->sb.s,ps->sb.d,ps->name,ps->age,ps->id);
}
#include <stdio.h>
int main()
{
struct Stu s = { {'w',20,3.14},"张三",18,"20200543 " };
//写一个函数打印s的内容
print1(s);//传值调用(更安全)
print2(&s);//传址调用(效率更高,节约空间)
return 0;
}
print2函数更优的原因:函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降。
所以结构体传参的时候,要传结构体的地址。
函数调用的参数压栈
栈,是一种数据结构,先进的后出,后进的先出。
可以把栈看为一个四周密闭的盒子,从栈顶(盒子的上)往栈底(盒子底部)存放数据,给栈存放数据的过程就叫压栈。而出栈只能从顶部开始往下删除。
举个例子:
int Add(int x, int y)//5.又找了一块区域分配给了Add
{
int z = 0;//在Add的空间底部存放z
z = x + y;//然后将x,y相加的结果返回给z
return z;//返回z
//6.返回的时候就开始销毁这块内存空间,从上往下开始销毁,先销毁Add的空间,然后销毁形参的空间。
}
#include <stdio.h>
//1.每一个函数调用都会在内存的栈区上开辟一块空间
int main()//2.调用main函数实际上在栈区开辟了一块空间
{
int a = 3;//3.在main的空间底部开始存放数据
int b = 5;
int c = 0;
c = Add(a,b);//4.函数传参通常情况是从右向左传的,所以先为b开辟一块空间,然后在b的上面为a开辟一块空间,函数传参的这个操作和压栈很相似,所以也叫压栈操作
return 0;
}
描述有些抽象,看图就能很好的理解了:
本章完。