- 结构体类型的声明
- 结构体变量的定义和初始化
- 结构体成员访问
- 结构体传参
自学b站“鹏哥C语言”笔记。
一、结构体类型的声明
1.结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
2.结构的声明
struct tag
{
member-list;
}variable-list;
- struct 结构体关键字
- tag 结构体标签(可以随意替换)
- struct tag 结构体类型
- member-list 成员变量列表
-
variable-list 变量列表(可省略)
- 大括号{ }后的分号 ; 不能少,因为声明是一条语句
例1:
//描述一个学生,需要一些数据,如名字、年龄、电话、性别
struct Stu
{
char name[20];
short age;
char tele[12];
char sex[5];
};
int main()
{
struct Stu s1;
struct Stu s2;
struct Stu s3;
return 0;
}
可以改写为:(区别是上面这段代码的s1,s2,s3是局部变量,下面的是全局变量)
struct Stu
{
char name[20];
short age;
char tele[12];
char sex[5];
}s1,s2,s3;
扩展:用typedef
可以对结构体类型进行改名
typedef struct Stu
{
char name[20];
short age;
char tele[12];
char sex[5];
}Stu;//更改类型名为Stu
int main()
{
Stu s1;//创建变量时的类型名为Stu,继续使用struct Stu也可以
Stu s2;
Stu s3;
return 0;
}
3.结构成员的类型
结构成员的类型可以是标量(普通变量)、数组、指针,也可以是其他结构体。
二、结构体变量的定义和初始化
(1)声明类型的同时定义变量
struct Point
{
int x;
int y;
}p1;
(2)单独定义变量
struct Point
{
int x;
int y;
};
int main()
{
struct Point p2;
}
(3)初始化:定义变量的同时赋初值,用大括号{ }表示
struct Point
{
int x;
int y;
};
int main()
{
struct Point p3 = {1, 2};
}
(4)初始化:结构体嵌套初始化
struct S
{
int a;
char c;
char arr[20];
double d;
}
struct T
{
char ch[10];
struct S s;
char* pc;
}
int main()
{
char arr[] = "hello bit\n";
struct T t = {"hehe", {100, 'w', "hello world", 3.14}, arr};//里面的结构体也需要用大括号{}
//访问时用.连接
printf("%s\n", t.ch);//hehe
printf("%s\n", t.s.arr);//hello world
return 0;
}
三、结构体成员访问
1.结构体成员访问的方式
结构体 . 成员名
结构体指针 -> 成员名
例1:
struct Stu
{
//放学生的一些相关属性
char name[20];
int age;
char id[20];
}Stu;
void Print1(Stu tmp)
{
//用.来访问结构的成员
printf("%s\n", s1.name);
printf("%d\n", s1.age);
printf("%s\n", s1.id);
}
void Print2(Stu* tmp)
{
//用->来访问结构的成员
printf("%s\n", ps->name);
printf("%d\n", ps->age);
printf("%s\n", ps->id);
}
int main()
{
Stu s = {"张三", 20, "20230104"};
Print1(s);
Print2(&s);
//两个函数打印的结果是一样的
return 0;
}
两种方法中较优的是用指针访问。考虑传参时占用的空间,Print1需要创建一个和s相同大小的空间,而Print2只需要创建一个指针大小(4/8字节)即可。
函数传参的时候, 参数是需要压栈的。如果传递一个结构体对象时,结构体过大,参数压栈系统开销过大,会导致性能下降。
2.补充说明:压栈
C语言中的内存:
栈区 |
局部变量
函数的形式参数
函数调用开辟空间
|
堆区 |
动态内存分配
涉及的函数:malloc/free,realloc,calloc等
|
静态区 |
全局变量
静态变量
|
数据结构:
线性数据结构 |
顺序表
链表
栈:先进后出。插入一个元素叫压栈,删除一个元素叫出栈
队列
|
树形数据结构 |
二叉树 |
图 |
|
四、结构体传参
由上一部分【三、结构体成员访问】得到结论:
结构体传参的时候,优先选择传结构体的地址。