一、结构体、结构体数组、结构体指针
1.结构体
1.1结构体定义
在开发过程中,嵌入式系统会接收到上位软件传输给我们的各种不同类型的变量,并且需要将他们关联在一起,这个时候就引入了结构体这一概念,结构体就是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。简单的理解,结构体就是所有想归类到一起的值都放置在一起的过程。
声明一个结构体类型的一般形式为:
struct 结构体名
{ 成员表列 };
struct Device
{
int status;
char num[20];
char device_name;
float power;
};
以上为一个最简单的结构体,但是在日常的使用过程中,由于代码的实际需求,需要在结构体里面套用结构体,成员可以属于另一个结构体类型。
struct Date
{
int year;
int month;
int day;
};
struct People
{
int num;
char name[20];
int age;
struct Date birthday; //成员birthday属于struct Date类型
char addr[30];
};
1.2定义结构体类型变量
在1.1中,我们首先进行了结构体的声明,那么当我们进行声明后,如何使用结构体呢,接下来我们对已经声明的结构体定义结构体类型变量。
struct Device device1, device2;
举个例子,比如我现在有两个设备,两个设备都包含固定的一些参数,但是当上位软件需要设置其中一个设备的参数中的具体某一个值的时候,另一个设备参数不进行改变时,我就需要提前给他们单独起一个名字device1和device2,这样就显得比较灵活。
struct Device
{
int status;
char num[20];
char device_name;
float power;
} device1, device2;
该种方式的一般形式为
struct 结构体名
{
成员表列
} 变量名表列;
1.3结构体成员赋值
由于结构体成员为变量值,因此我们在进行赋值时可以直接进行 device.status = x 这种方式进行赋值操作(.型赋值方式)
2.结构体数组
2.1结构体数组理解
结构体数组的本质是将结构体进行多次引用,引用的主体为一个数组形式,这样可以在数组中给所需的结构体进行赋值操作
2.2结构体数组定义
struct 结构体名
{成员表列
} 数组名[数组长度];
在声明结构体数组时可以使用下面一般形式进行声明
结构体类型 数组名[数组长度];
3.结构体指针
3.1结构体指针的理解
在C语言的指针中,指针指向的是变量所占内存的首地址,以此类比,结构体指针指向的是该结构体变量的起始地址
3.2结构体指针的定义
struct 结构体名* 指针名
当我们在使用结构体指针进行嵌入式代码编写时,我们需要为结构体指针以及成员内的指针使用malloc()函数申请内存空间大小,否则我们在进行数据的存储以及读写时会报错。
/*结构体定义*/
struct system_context{
int spi_buff;
struct cmd *cmd;
struct status *status;
struct ringBuffer *cmd_buf;
struct DeviceParam *device_params;
};
/*结构体内存申请*/
struct system_context *device = (struct system_context* )malloc(sizeof(struct system_context));
在上述代码中,我们首先定义了一个包含指针成员的结构体,然后将该结构体引用为指针结构体,那么问题来了,我们既可以设结构体也可以设为结构体指针,那么两者包含什么差别呢,为什么实际的使用过程中,大家更倾向于使用结构体指针,下面为大家浅谈一番。
struct system_context device;
struct system_context *device;
struct system_context device;
这种方式我们将内存分配至栈上,这种方式我们在实际的使用过程中并不需要使用mallco函数对其进行内存的申请,它可以进行自动的释放;但是栈空间有限、变量无法在超出其作用域后使用,对于项目而言,这种方式的局限性很高。
struct system_context *device;
这种方式实际上我们进行的是动态分配指针,结构体存在堆上,这种情况需要我们手动的对其进行内存申请,并需要通过调用free(device)进行内存释放,这样的方式相对比第一种方式我们看似很复杂,并且很麻烦,但是这种方式可以在函数返回后继续使用、避免栈溢出、可跨作用域传递,因此我们一般使用这种方式进行操作。
如上面代码所示,我们在进行结构体的定义时候,发现内部还包含结构体指针,那么我们在最初始时,同样需要给其申请内存。
/*分配内存*/
struct system_context *device = (struct system_context* )malloc(sizeof(struct system_context));
if(!device){
printf("allocate device failed\n");
return -1;
}
mamc->cmd = (struct cmd* )malloc(sizeof(struct cmd));
if(!mamc->cmd){
printf("allocate cmd failed\n");
return -1;
}
//.........