指针类型是一种用户自定义的简单类型,它的值集 是由一些内存地址(指针)构成。
指针,在定义时,在变量名前加入“*”。有一点需要注意的是,指针前的数据类型,如:
int * P; //该指针指向的数据为int类型,占4个字节,这在从地址中取出数据非常重要
void * P; //该指针指向类型为void,也就是通用数据类型,从地址中取不出数据,但是它在使用中有着重要
//作用,特别在参数传递过程中
指针有一个重要功能就是可以从地址中取出数据,我们称为“镖”,用“*”实现;普通的数字类型也有个功能,就是取其地址,我们称为“钩子”,用“&”来实现。
一·数据指针
在ESP32开发过程中,我们可以使用指针来进行参数的传递,这里,我以创建任务为例进行说明,如下:
#define led 12
void set_up(void){
vTaskCreate(
Task1,
"Task1",
1024,
(void *)&led, //将led的地址取出来,并强制类型转换成void *
1,
NULL);
}
void Task1(void *P){
byte led = *(byte *)P; //将P强制转换成byte * ,并取出地址中数据
pinMode(led,OUTPUT)
while(1){
digitalWrite(led,LOW);
vTaskDealy(100);
}
}
二·结构体指针
当我们需要进行多个参数传递时,我们可以使用自定义结构体指针来实现,如下:
//也可以用typedef创建新类型
typedef struct{
byte pin;
int delaytime;
}LED;
void set_up(void){
LED LED_led;
LED_led.pin = led;
LED_led.delaytime = 1000;
vTaskCreate(
Task1,
"Task1",
1024,
(void *)&LED_led, //将led的地址取出来,并强制类型转换成void *
1,
NULL);
}
//错误使用方法
void Task1(void *P){
struct led = *(struct *)P; //将P强制转换成byte * ,并取出地址中数据
pinMode(led.pin,OUTPUT)
while(1){
digitalWrite(led.pin,LOW);
vTaskDealy(led.delaytime);
}
}
//正确使用方法
void Task1(void *P){
struct led = *(struct *)P; //将P强制转换成byte * ,并取出地址中数据
byte pin = led.pin;
int delaytime = led.delaytime;
pinMode(led.pin,OUTPUT)
while(1){
digitalWrite(pin,LOW);
vTaskDealy(delaytime);
}
}
//or
void Task1(void *P){
struct * led = (struct *)P; //将P强制转换成byte * ,并取出地址中数据
byte pin = led->pin;
int delaytime = led->delaytime;
pinMode(led.pin,OUTPUT)
while(1){
digitalWrite(pin,LOW);
vTaskDealy(delaytime);
}
}
这里对错误使用方法进行说明,在set_up执行完成后,原本LED_led的地址空间会被释放,对于一些内存小的MCU来说,被释放的内存会再次被其他变量所使用。解决方法:可以将其定义成全局变量,在程序运行过程中不会被释放。
在上述代码中涉及到了结构体成员变量的使用,对于非地址结构体变量,使用“.”;对与指针结构体变量,使用“->”.
在上述过程中我们可以看到(void *)指针的重要性。