这篇文章主要讲述什么是指针的指针,有什么用途。
在freeRTOS中,有一个创建动态任务的函数,
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
我们重点观察最后一个参数,
typedef struct tskTaskControlBlock * TaskHandle_t;
TaskHandle_t * const pxCreatedTask
可以看到,这个参数其实就是指针的指针。
首先我们先看第一段代码
int set_val(int a)
{
a=123;
}
int main()
{
int b=0;
set_val(b);
}
可以看到这段代码想做的事情是改变b的值,我们想要b=123,但实际输出的确实b=0,这是因为a是一个局部变量,局部变量的作用域只在这个函数内部,b只做了一个传参,执行代码的实际效果是
a=b=0;
a=123;
那我们怎么做?看下一段代码。
int set_val(int *a)
{
*a=123;
}
int main()
{
int b=0;
set_val(&b);
}
可以看到,set_val实际传入的参数是b的地址,此时的a指向了b的地址,*a=123实际上就是将123写入了b的地址,所以b=123。
再深一步引申
typedef int* TYPE
int get_int_pointer(TYPE *v)
{
int *p = malloc(4); //申请一块四字节的空间。
并返回申请空间的地址
*v = p; //p保存的是一个地址
}
int main()
{
TYPE b;
get_int_pointer(&b);
}
这代码怎么理解?这段代码所作的事情和上一段程序的类似。
- 将b的地址作为参数传入了get_int_pointer;
- 将v指向了b的地址;
- 将申请得到的空间首地址赋给*v;
- 最后b的值为p
也就是说,最后的效果是,b指向了p所指向的地址,即把这段空间的首地址赋给了b,通过b就可以访问到申请的空间。b是一个指针的指针。
最后回到我们一开始引入的 xTaskCreate()函数,
typedef struct tskTaskControlBlock * TaskHandle_t;
TaskHandle_t * const pxCreatedTask
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask )
观察最后一个参数,这个参数代表的是任务结构体,我们传入的应该是任务结构体的指针。
与上段代码类似
TYPE b;
get_int_pointer(&b);
我们传入参数为
TaskHandle_t * xHandlerTask;
xTaskCreate(,,,,,&xHandlerTask);
我们获得的是分配好的任务结构体的地址。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)