C语言程序设计笔记---014
C语言结构体初阶
/知识点汇总/
1、结构体的基础知识
a、结构是一些值的集合,这些值称为成员变量
b、结构的每个成员可以是不同类型的变量
c、结构体成员可以是变量,数组,指针,甚至是其他结构体
d、结构体成员中可以有另外一个结构体
1.1、结构的声明例程
/*例程1.1*/
#include <stdio.h>
//结构的声明
//struct stu
//{
// //成员变量,成员可以为不同类型的
// char name[20];
// int age;
// char id[20];
//};
struct stu
{
//成员变量,成员可以为不同类型的
char name[20];
int age;
char id[20];
}s1,s2;//s1,s2也是结构体变量
//但s1,s2是全局变量
int main()
{
//创建结构体对象--s
struct stu s;//s为局部变量
return 0;
}
1.2、结构体成员中可以有另外一个结构体例程
/*例程1.2*/
#include <stdio.h>
struct B
{
char c;
short s;
double d;
};
struct stu
{
struct B abc;//结构体嵌套
char name[20];
int age;
char id[20];
}s1,s2;//结构体全局变量
//结构体的初始化也是{ }号
int main()
{
//结构体中的另一个结构体,也用{成员...}
struct stu s = { {'w',20,3.14159},"张三",30,"2020D2780124" };//结构体面向对象
return 0;
}
1.3、结构体成员的访问例程
主要操作符为:. ->
/*例程1.3*/
#include <stdio.h>
struct B
{
char c;
short s;
double d;
char* f;//指针类型成员·
};
struct stu
{
struct B abc;
char name[20];
int age;
char id[20];
}s1, s2;
int main()
{
//结构体初始化
struct stu s = { {'w',20,3.14159,'F'},"小强",18,"2020D2780106" };//对象
//. ->
//printf("%c\n",s.abc.c);
//printf("%c\n", s.abc.f);
struct stu* ps = &s;//结构体指针变量
printf("%c\n",(*ps).abc.c);//*解引用+ .成员运算符,获取对应的结构体成员
printf("%c\n", ps->abc.c);//->根据对象的指针,直接访问成员,即取结构体内成员
return 0;
}
1.4、结构体传值/传址调用例程
/*例程1.4*/
#include <stdio.h>
struct B
{
char c;
short s;
double d;
};
struct stu
{
struct B sb;
char name[20];
int age;
char id[20];
};
//print1:传值调用
void print1(struct stu t)
{
printf("%c %d %.2lf %s %d %s\n",t.sb.c,t.sb.s,t.sb.d,t.name,t.age,t.id);
}
//print2:传址调用
void print2(struct stu* ps)
{
printf("%c %d %.2lf %s %d %s\n", ps->sb.c, ps->sb.s, ps->sb.d, ps->name, ps->age, ps->id);
}
int main()
{
struct stu s = { {'w',20,3.14},"张三",30,"2020D12458" };
//写一个函数打印s的内容
print1(s);
//调用指针,取地址s
print2(&s);
return 0;
}
小结:
a、传值/传址调用,传址更具优势:节约内存的空间,且速率更快
b、函数在传参时,参数是需要压栈的,如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
即:结构体传参时,常传结构体的地址
2、函数调用时的参数压栈
栈—是一种数据结构
压栈/出栈:
理解为,盒子自上向下装,直到装满压紧,取出是却是后进先出,自上往下取出
参数压栈:
每一个函数的调用都会在内存的栈区上开辟一块区域(栈区、堆区、静态区)
特点:先进后出,后进的先出
2.1、结构体参数压栈例程
/*例程2.1*/
#include <stdio.h>
int Add(int x, int y)
{
int z = 0;
z = x + y;
return z;
}
int main()
{
int a = 3;
int b = 5;
int c = 0;
c = Add(a,b);
return 0;
}
2.2、参数压栈解释说明
理解:每一个函数的调用都会在总的内存的栈区上开辟一块区域,然后会暂时存储变量的内存,然后每次调用一次函数也会开辟一块内存区域,像叠盘子一样,越跌越高,形成了堆叠,也就是压栈。直到函数执行完,里面的局部变量使出作用域,相继内存也得以释放,就像把刚堆叠的盘子再从上向下,拿取出去,也就是释放了空间。
如图所示:
总结就是:先进后出,后进先出
3、函数栈帧的创建与销毁
可参考这位博主,写得很好:
链接: 函数栈帧的创建与销毁