结构体
本章浅入了解结构体,在后面的自定义类型进阶会重点讲这部分内容。
文章目录
- 一、结构体类型的声明
- 二、结构体初始化
- 三、结构体成员访问
- 四、结构体传参
一、结构体类型的声明 结构体:用于描述属性不止一个的复杂对象
结构体是一些值的集合,这些值成为成员变量,且结构的成员可以是不同类型变量。我们已经学习过:
int
、char
、float
、double
等单一变量类型,但这些只能描述单一属性,所以C语言创造了包含多种单一变量结构体,方便描述复杂对象。比如一本书有书名、作者、价格等属性。结构体的声明语法:
struct tag//struct - 结构体关键字;tag - 结构体标签;struct tag - 结构体类型名
{
member-list;
//成员列表
}variable-list;
//变量列表
如要声明一个学生类型,它的成员变量包括:名字、年龄、性别、学号。int类型
本身不占据空间,当用int类型
创建int整型变量
时才会在内存中开辟空间。
同理,struct tag结构体类型
本身不占据空间,当用结构体类型
创建结构体变量
才会在内存中开辟空间
struct Stu
{
//成员变量
char name[20];
//名字
int age;
//年龄
char sex[5];
//性别
char id[20];
//学号
};
当觉得上述
struct Stu
结构体类型名太长,这时候需要用到类型重定义typedef
typedef struct Stu
{
//成员变量
char name[20];
//名字
int age;
//年龄
char sex[5];
//性别
char id[20];
//学号
}Stu;
【C语言基础|【C语言入门必看】结构体】这样,结构体成员的类型:struct Stu
就等效于Stu
结构的成员可以是标量、数组、指针,甚至是其他结构体(内嵌)。
二、结构体初始化 有了结构体类型,定义结构体变量就简单啦!
struct Stu
{
//成员变量
char name[20];
//名字
int age;
//年龄
char sex[5];
//性别
char id[20];
//学号
}s1;
//①声明类型的同时定义变量s1
struct Stu s2;
//定义全局变量s2
int main()
{
struct Stu s3;
//③定义局部变量s3
struct Stu s4 = { "张三",17,"男","20200360318" };
//④定义结构体变量s4的同时可初始化
return 0;
}
以上是创建结构体变量的方式。当执行类型重定义注:在typedef struct {...} Stu;
后代码中的struct Stu
可替换成Stu
。
main
函数内创建的结构体变量是局部变量,在栈区开辟空间;在main
函数外,则为全局变量,在静态区开辟空间。结构体内可嵌套结构体:
struct S
{
int a;
char c;
double d;
};
struct T
{
struct S s;
char name[20];
int num;
};
int main()
{
struct T t = { {100, 'w', 3.14}, "张三", 17 };
return 0;
}
结构体变量t内含有用三、结构体成员访问结构体类型S
创建的s
。在给s
初始化时,得用{}
。
.
操作符
结构体变量成员可通过.
操作符访问,它有两个操作数,左边为结构体变量名,右边为结构体成员变量名。
借用上面结构体嵌套的例子:
文章图片
s
是t
的成员变量,a
,b
,c
是s
的成员变量,访问a
,b
,c
则为t.s.a
,t.s.b
,t.s.c
->
操作符
结构体变量成员也可通过->
操作符访问,它有两个操作数,左边为结构体指针变量,右边为结构体成员变量。
struct T t = { {100, 'w', 3.14}, "张三", 17 };
struct T* pt = &t;
//结构体指针变量pt
//1.对结构体指针解引用找到指针所指向的结构体
printf("%d %c %lf %s %d\n", (*pt).s.a, (*pt).s.c, (*pt).s.d, (*pt).name, (*pt).num);
//2.通过结构体指针直接获得成员变量
printf("%d %c %lf %s %d\n", pt->s.a, pt->s.c, pt->s.d, pt->name, pt->num);
四、结构体传参
#include
struct S
{
int data[1000];
int num;
};
//结构体类型的声明//结构体传参
void print1(struct S s)
{
printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
printf("%d\n", ps->num);
}
int main()
{
struct S s = { {1,2,3,4}, 1000 };
print1(s);
//传结构体
print2(&s);
//传地址
return 0;
}
上面的
print1
和 print2
函数哪个好些?答案是:首选
print2
函数。原因:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。结论:
结构体传参的时候,建议传结构体的地址。
推荐阅读
- C语言基础|【C语言入门必看】指针
- C语言进阶|【详解C语言指针】我真的让C指针给我唱征服了~乌拉
- 《C陷阱与缺陷》读书笔记--第一章语法陷阱1
- C语言|C语言两种方法计算一个数所有位上的数的总和
- C语言|C语言实现简单计算器
- Kubernetes|Kubernetes 中的服务发现与负载均衡
- 蓝桥杯|蓝桥杯第十届C语言b组——B: 年号字串
- 蓝桥杯|蓝桥杯.颠倒的价牌(暴力枚举)
- 蓝桥杯|萌新打卡 蓝桥杯 算法基础 暴力枚举——立方和等式 暴力大法好