初识结构体

时间:2023-01-07 10:01:32
  • 结构体类型的声明
  • 结构体变量的定义和初始化
  • 结构体成员访问
  • 结构体传参

自学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等

静态区

全局变量

静态变量

数据结构:

线性数据结构

顺序表

链表

栈:先进后出。插入一个元素叫压栈,删除一个元素叫出栈

队列

树形数据结构

二叉树


四、结构体传参

由上一部分【三、结构体成员访问】得到结论:

结构体传参的时候,优先选择传结构体的地址