今日开始为电赛复习一些必备的算法知识,本文回顾复习结构体的概念以及一些基本操作,每个知识点都有代码实践演示,可以复制测试查看!
目录
前言——往日的困惑:
一、结构体基础知识与用途:
C语言结构体是一种自定义数据类型:
结构体可以包含不同的数据类型:
结构体包含以下要素与使用方式:
结构体的主要用途:
结构体的一般定义形式:
结构体可以理解为存数据的模板:
结构体可以理解为自己定义的一种数据类型:
结构体的大小如何计算:
结构体基础知识编程实战强化:
二、结构体组员的访问,结构体组员变量的初始化:
三、结构体数组的使用:
四、结构体指针访问结构体组员:
五、结构体可被typedef 重定义:
前言——往日的困惑:
我在大一初学C的时候的感受是十分痛苦的:一些简单函数的学习可以随便看俩篇文章或查阅教科书完成,但遇到一些知识点比较多的结构思想时,学起来是十分没有效率的,当时我为了学习结构体,查阅过大量他人写的博客笔记,发现都写得不尽完整,导致浪费了大量时间去自己整合学习结构体的知识,写本文时我已经写了近一年有关单片机嵌入式的代码了,已不再是大一时热爱算法的少年,因此从今日开始,我打算学习充实自己的算法知识与实践能力,并做分享。
为了让个位看官不再被不完整的博文困扰,我争取写出完整的结构体知识复习文章,争取一篇文章解决大家的疑问,学会一些结构体的使用手段!
一、结构体基础知识与用途:
C语言结构体是一种自定义数据类型:
它允许将不同类型的数据组合在一起,并赋予其一个名称,以便更容易地管理和操作这些数据。结构体是一种非常有用的工具,用于定义和操作复杂的数据结构,实现数据的封装、传递和处理等功能。
结构体可以包含不同的数据类型:
如整数、浮点数、字符等,甚至可以包含其他结构体。
结构体包含以下要素与使用方式:
1.名称:结构体是自己定义的数据类型或模板,一个程序项目中不同用途的结构体需要有不同的名称来区分。
2. 数据成员:结构体可以包含多个不同数据类型的成员,这些成员可以是基本数据类型(如整数、浮点数、字符等),也可以是其他自定义的数据类型(如数组、指针、其他结构体等)。
3. 结构体变量:通过结构体定义的模板,可以创建多个实际的结构体变量,每个实例都具有相同的结构和成员,但可以存储不同的数据。
4. 访问成员:可以使用结构体变量名和成员名的组合来访问结构体的各个成员,并进行读取或赋值操作。
5. 结构体指针:可以使用指向结构体的指针变量,通过指针来访问和操作结构体的成员,可以实现更灵活的操作方式。
6. 结构体嵌套:结构体可以作为其它结构体的成员,从而实现更复杂的数据组织和层次化结构。
7. 结构体作为函数参数:可以将结构体作为函数的参数进行传递,通过引用传递可以修改结构体的值,从而实现对结构体数据的批量处理和操作。
8. 结构体作为函数返回值:函数可以返回结构体类型的数据,从而方便地返回多个不同类型的结果。
结构体的主要用途:
1. 定义复杂的数据结构:结构体可以用于定义更复杂的数据结构,比如链表、树等。通过将不同类型的数据组合在一起,可以更好地组织、访问和操作数据。
2. 数据封装:结构体可以将相关的数据封装在一起,形成一个单个实体,从而更好地进行管理。通过封装数据,可以提高代码的可读性、可维护性和可扩展性。
3. 传递和返回多个值:使用结构体可以方便地传递和返回多个值,而不需要使用单独的参数或全局变量。这对于某些函数需要返回多个结果或需要传递多个相关的参数时非常有用。
4. 数据库和文件处理:结构体可以方便地表示和处理数据库中的记录,以及文件中的数据。通过定义适当的结构体,可以更好地管理数据库和文件的数据。
结构体的一般定义形式:
struct + 结构体名称
{
成员列表;
};
结构体变量的定义可以放在结构体的声明之后:
struct Student //定义一个名为Student的结构体
{
char name[20]; //姓名
int id; //学号
int age; //年龄
};
struct Student stu; //定义一个结构体变量
结构体变量的定义也可以在结构体声明的同时定义,这样就简化了代码:
struct Student //定义一个名为Student的结构体
{
char name[20]; //姓名
int id; //学号
int age; //年龄
}stu; //在结构体声明的同时定义一个结构体变量stu
结构体可以理解为存数据的模板:
此处注意旨在讲明,结构体是从什么时候开始才占用内存空间的:
结构体它并不实际储存数据,它本身不分配内存空间来存储实际数据,我们不能将其看作一个或者很多变量,正确理解它的方式应该是将其看作一种存储数据的模板,数据会以我们对结构体定义的方式进行排列组合,只有我们定义结构体变量或者结构体数组时,才会申请分配一块空间来存储实际的数据。
结构体可以理解为自己定义的一种数据类型:
此处为解明,结构体定义完后,再定义结构体变量是什么意思,可以类比为什么。
我们从上表可以了解到,int是C语言中的一个基本数据类型,它本身不占用空间,只有在我们用这个数据类型定义变量时会开辟一条空间,比如我定义了int a;此时就会为变量a开辟一片4字节的空间,我们也可如此认为,结构体与int类似,只不过它存储的数据成员有哪些、结构体名称是什么,都要我们自行定义,比如我定义一个结构体,名称是student,定义完结构体后,student就可以被看做一个数据类型的名称了,我可以用其定义变量了,比如:struct student B;这样就定义了一个结构体变量B,后续我们也会学习如何获取它每个成员的数据。
结构体的大小如何计算:
我们定义完结构体变量B之后,其占用内存空间大小该怎么计算呢?
首先列出一些 常用数据类型的占用内存大小:
在C语言中,常用的数据类型及其所占的内存大小(在一般情况下)如下所示:
1. char:1字节
2. int:4字节
3. float:4字节
4. double:8字节
5. short:2字节
6. long:4或8字节(取决于操作系统)
7. long long:8字节
8. unsigned char:1字节
9. unsigned int:4字节
10. unsigned short:2字节
11. unsigned long:4或8字节(取决于操作系统)
12. unsigned long long:8字节
结构体占用内存大小可以通过函数直接计算:
可以直接用sizeof进行计算:sizeof(struct MyStruct);
结构体基础知识编程实战强化:
学习实现的功能如下:
定义一个结构体,定义结构体变量,并输出计算其占用内存大小
代码:
#include "stdio.h"
//定义结构体
struct student{
char name;
int age;
};
int main()
{
//定义结构体变量B
//利用结构体去定义变量的时候,必须加上struct,不能省略
struct student B;
//定义变量用于存储计算结构体大小
int size;
//计算结构体大小
size=sizeof(struct student);
//输出这个大小
printf("%d",size);
return 0;
}
结果演示:
二、结构体组员的访问,结构体组员变量的初始化:
虽然结构类似一个数组,只是数组每个元素的数据类型都是相同的,而结构中每个元素成员的数据类型是可以不同的。
结构体不像数组那样使用下标去访问其中的各个元素,而用结构体成员运算符点(.)。
即访问成员的一般形式是:结构体变量名.成员名
在定义完结构体,在定义结构体变量以后,我们可以与定义变量一样给它立即初始化一些值。
接下来直接进行编程实战展示:
学习实现功能:
1.定义结构体、结构体变量
2.定义结构体变量时就初始化结构体变量的成员值,并直接输出打印
3.改变结构体变量成员的值,并输出
代码:
#include "stdio.h"
//定义结构体
struct student{
char name;
int age;
};
int main()
{
//定义结构体变量B
//利用结构体去定义变量的时候,必须加上struct,不能省略
//同时初始化组员 name与 age 分别为 A 18
struct student B={'A',18};
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",B.name,B.age);
//改变结构体变量B组员 age的值
B.age=21;
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",B.name,B.age);
return 0;
}
结果演示:
普通变量访问结构体成员的值只需用“=”即可:
//定义结构体
struct student{
char name;
int age;
};
struct student B={'A',18};
int AB;
AB=B.age;
三、结构体数组的使用:
我们从类比普通的数据类型开始讲解,比如大家最熟悉的int,我们都知道语句int A;可以定义一个变量A来存储整数形数据,当我们需要一连串有规律、有1~9之类的下标,得以便捷访问的许多整形数据时,就需要定义一个整数形数组了:int A[10];
当然,我们之前有了解过,结构体可以看作为数据类型,因此也可定义为数组形式!
我们直接实战学习一下:
1.定义结构体、结构体数组
2.输出结构体数组
代码:
#include "stdio.h"
//定义结构体
struct student{
char name;
int age;
};
int main()
{
int i;
//定义结构体数组 有5个下标
struct student AB[5];
//改变结构体各个数组变量各个组员的值
AB[0].name='A';AB[0].age=18;
AB[1].name='B';AB[1].age=19;
AB[2].name='C';AB[2].age=20;
AB[3].name='D';AB[3].age=21;
AB[4].name='E';AB[4].age=22;
AB[5].name='F';AB[5].age=23;
for(i=0;i<5;i++)
{
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",AB[i].name,AB[i].age);
}
return 0;
}
结果演示:
四、结构体指针访问结构体组员:
指针与指针变量是两个不同的概念,指针是某个普通变量的地址,所以可以理解为,指针就是地址,地址就是指针。指针变量是一种变量,它的作用是存储其它变量的地址。
指针就是一个变量,用来存放地址,地址标识一块空间。
以下代码是使用指针操作char数据类型的实例:
int main()
{
char ch = 'w'; //创建一个char类型的变量去存放字符'w'
char *pc = &ch;//创建一个字符指针变量,去存放
*pc = 'a';//将字符'a'存放到pc地址所指向的字符,也就是把pc所指向的字符更改成字符'a'
return 0;
}
经过以上代码的学习,我们发现,结构体也是一种数据类型,因此也可以被指针指向结构体的地址:
关键代码:
//定义一个结构体指针p去指向结构体变量B
struct student *p = &B;
(*p).name = 'B'; //等价于p -> name= 'B'; //名字修改为B
(*p).age = 23; //等价于p -> age = 23; //将年龄修改为23
全部代码:
起初结构体存的是 name=A,age=18,并先打印输出
在定义结构体指针指向地址,修改指针后,变成了name=B,age=23,并打印输出
#include "stdio.h"
//定义结构体
struct student{
char name;
int age;
};
int main()
{
//定义结构体变量B
//利用结构体去定义变量的时候,必须加上struct,不能省略
//同时初始化组员 name与 age 分别为 A 18
struct student B={'A',18};
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",B.name,B.age);
//定义一个结构体指针p去指向结构体变量B
struct student *p = &B;
(*p).name = 'B'; //等价于p -> name= 'B'; //名字修改为B
(*p).age = 23; //等价于p -> age = 23; //将年龄修改为23
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",B.name,B.age);
return 0;
}
【注】结构体成员如果是字符串,不能直接通过赋值号“=”去修改值,可以通过C语言中的拷贝函数strcpy去修改值。
五、结构体可被typedef 重定义:
typedef 为C语言的关键字,作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
使用 typedef 定义新类型的方法(步骤):
在传统的变量声明表达式里,用(新的)类型名替换变量名,然后把关键字 typedef 加在该语句的开头就可以了。
但此处的替换的意思不是说原先的关键字不能用了:
比如我写了typedef int u32;
此句是给int 这个关键字起了一个别名,叫u32,
以后我想定义一个int类型的数据,可以这么写:u32 A;(等价与 int A;)
并且int A;这样的写法依旧合法,可以使用。
而在结构体中的用法如下:
#include "stdio.h"
//重定义结构体 student名称为 ST
typedef struct student{
char name;
int age;
}ST;
//重定义的名称 ST可以理解为 写ST就等价于写struct student
int main()
{
//定义结构体变量B ,我们可以发现此时不需要写 struct了,节省了代码量
//同时初始化组员 name与 age 分别为 A 18
ST B={'A',18};
//访问输出结构体变量B的俩个组员name与 age
printf("name=%c,age=%d\n",B.name,B.age);
return 0;
}
可以发现,定义结构体变量B 时不需要写 struct了,节省了代码量!
结果演示: