C语言(结构体)
目录
1、前言
2、结构体变量的使用
2、1 为什么要使用结构体
2、2 结构体的定义规则
2、3 结构体成员的访问
2、4 结构体与typedef
2、5 结构体的大小
3、结构体数组
4、结构体指针
1、前言
结构体是嵌入式工程师非常常用的数据类型,在开发大型项目中,里面用到结构体的频率是非常高的,举个例子,在RTOS队列中互相传数据,总不能一个变量创建一个队列吧,那代码量和整洁度将会变得非常糟糕,而且在链表等数据结构中使用结构体的频率也是非常高的,有必要好好掌握结构体,进阶成为嵌入式工程师
2、结构体变量的使用
2、1 为什么要使用结构体
首先我们为什么要用到结构体,我们都已经学了很多int char …等类型还学到了同类型元素构成的数组,以及取上述类型的指针,在一些小应用可以灵活使用,然而,在我们实际应用中,每一种变量进行一次声明,再结合起来显然是不太实际的,类如一位学生的信息管理,他可能有,姓名(char),学号(int)成绩(float)等多种数据。如果把这些数据分别单独定义,就会特别松散、复杂,难以规划,因此我们需要把一些相关的变量组合起来,以一个整体形式对对象进行描述,这就是结构体的好处。
🔑 官方来说结构体就是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。说到集合,数组也是集合,但是不同的是数组只能是相同类型元素的集合。
2、2 结构体的定义规则
结构体定义由关键字 struct 和结构体名组成,结构体名可以根据需要自行定义。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:
//定义一个结构体
struct Student {
//在内部创建你需要的数据类型
char name[10];
int age;
char sex[5];
};
上面的代码是我想创建一个类型来描述一个学生的信息,我将学生名字、年龄、性别创建在了一个名叫Student的结构体中,这样一来我们就创建好了自己定义的一个结构体。
注:结构体中的内容可依据需求自行创建,一般来说结构体的创建都是在代码最开始的地方创建,并且要注意在创建好结构体之后要加上 ;(分号)!
注意:
▶结构体也是一种数据类型,它由程序员自己定义,可以包含多个其他类型的数据。
▶只有结构体变量才分配地址,而结构体的定义是不分配空间的
▶结构体中各成员的定义和之前的变量定义一样,但在定义时也不分配空间
▶结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错
2、3 结构体成员的访问
为了访问结构的成员,我们使用成员访问运算符(.)。
引用形式:<结构体类型变量名> . <成员名>
注意:结构体变量不能整体引用,只能引用变量成员
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct data
{
char name[20]; //姓名
int num; //学号
int age; //年龄
char group; // 所在小组
float score; // 成绩
}
int main()
{
struct data stu1; //创建结构体变量
stu1 = { "Tom",12,18,'A',123.3f }; //给结构体
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f\n",
stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
//只能由结构体变量加结构体成员的方式来访问
return 0;
}
2、4 结构体与typedef
前面我们提过,结构体是程序员自定义的一种数据类型,既然是数据类型就可以与typedef联用,例如uint8_t就是unsigned char类型经过typedef重新定义的,结构体当然也可以重新定义成用户想要的名称
typedef struct student
{
int age;
int height;
}std;
//std相当于struct student
struct student
{
int age;
int height;
}std1,std2;
//定义了student数据类型的结构体和std1、std2结构体变量
2、5 结构体的大小
结构体中会有字节对齐这个概念,一般来说是根据字来定的,32位就是4字节,64位就是8字节,不满一字的按一字算,一字等于4字节或者8字节,其实就是用空间换时间,能提升cpu的效率
举个例子,在下列代码中,char是一字节,int是四字节,他不能跟在char的后面,所以char自己就得占用四字节,int占用4字节,short两字节+char一字节,按理说应该是占用十一字节的内存大小,但是根据字节对齐的概念来说,下一个地址开辟又是从一个新字节头部开始了,所以这个结构体所占的大小应该是十二字节
struct test
{
char ch;
int num;
short i;
char d;
};
3、结构体数组
结构体数组:是指数组中的每一个元素都式结构体。举个例子,我声明了一个结构体数组,而这个结构体数组可以看成由五个结构体变量组成的一个组合,class[0]是拥有strcut stu这个结构体类型所有成员的结构体,而class[1] class[2]等等与class[0]是没有任何区别的结构体,他们组合在一起组成一个结构体数组
struct stu
{
char name[20]; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}class[5];
//表示一个班有5个人
4、结构体指针
可以定义指向结构的指针,方式与定义指向奇特类型变量的指针类似。
定义类型:struct 结构体名 * 结构体指针名
struct books*struct_pointer
//定义结构体指针
struct_pointer = &Book1;
//结构体指针存入结构体变量地址
(*pointer).memberMane //pointer为结构体指针名
pointer->memberName //指针指向结构体成员地址
举个完整的例子看看就明白了,其运行的结果是相同的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stu
{
char name[20];
int num;
int age;
char group;
float score;
}stu1 = { "Tom",12,18,'A',136.5 }, * pstu = &stu1;
int main()
{
// 读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!\n", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
return 0;
}