FreeRTOS信号量的封装函数参数是二级指针
1. 先看正确的封装方式,问题所在,为什么要用2级指针
void cissys_lockcreate(void** mutex)
{
//创建信号量,应该是互斥锁
*mutex = ((SemaphoreHandle_t)xSemaphoreCreateMutex());
}
2. 错误的封装形式
void cissys_lockcreate(void** mutex)
{
//创建信号量,应该是互斥锁吧
mutex = &((SemaphoreHandle_t)xSemaphoreCreateMutex());
}
3. xSemaphoreCreateMutex的函数原型
#define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType )
{
Queue_t *pxNewQueue;
const UBaseType_t uxMutexLength = ( UBaseType_t ) , uxMutexSize = ( UBaseType_t ) ;
pxNewQueue = ( Queue_t * ) xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType );
prvInitialiseMutex( pxNewQueue );
return pxNewQueue;
}
4. 句柄的定义
typedef void * QueueHandle_t;
5. (参考别人的写法)看一下其他的解释,错误的写法
程序1:
void main()
{
char *p=NULL;
myMalloc(p); //这里的p实际还是NULL,p的值没有改变,为什么?
if(p) free(p);
}
void myMalloc(char *s) //我想在函数中分配内存,再返回
{
s=(char *) malloc();
}
myMalloc(p)的执行过程:
分配一个临时变量char *s,s的值等于p,也就是NULL,但是s占用的是与p不同的内存空间。此后函数的执行与p一点关系都没有了!只是用p的值来初始化s。
然后s=(char *) malloc(100),把s的值赋成malloc的地址,对p的值没有任何影响。p的值还是NULL。
注意指针变量只是一个特殊的变量,实际上它存的是整数值,但是它是内存中的某个地址。通过它可以访问这个地址。
6. (参考别人的写法)对比正确的写法
程序2:
void myMalloc(char **s)
{
*s=(char *) malloc();
}
void main()
{
char *p=NULL;
myMalloc(&p); //这里的p可以得到正确的值了
if(p) free(p);
}
程序2是正确的,为什么呢?看一个执行过程就知道了:
myMalloc(&p);将p的地址传入函数,假设存储p变量的地址是0x5555,则0x5555这个地址存的是指针变量p的值,也就是Ox5555指向p。
调用的时候同样分配一个临时变量char **s,此时s 的值是&p的值也就是0x5555,但是s所占的空间是另外的空间,只不过它所指向的值是一个地址:Ox5555。
*s=(char *)malloc(100);这一句话的意思是将s所指向的值,也就是0x5555这个位置上的变量的值赋为(char *)malloc(100)(并不是改变p的地址值0x5555,而是指针变量p本身的值),而0x5555这个位置上存的是恰好是指针变量p,这样p的值就变成了(char *)malloc(100)的值。即p的值是新分配的这块内存的起始地址。
7. 自己的总结
先假设一个二级指针,S--->P(0x3080)--->BUF1(0x1122),S是二级指针,P是一级指针,BUF1是第一个空间,假设参数是一级指针,那么我们只能修改BUF1的内容,S--->P(0x3080)--->BUF1(0x3344),假设参数是二级指针,那么我们可以修改P的值,S--->P(0x4080)--->BUF2(0x7788),就是P指向的空间从BUF1改成指向了BUF2。
FreeRTOS信号量的封装函数参数是二级指针的更多相关文章
- C语言 数组做函数参数退化为指针的技术推演
//数组做函数参数退化为指针的技术推演 #include<stdio.h> #include<stdlib.h> #include<string.h> //一维数组 ...
- C#中调用C++的dll的参数为指针类型的导出函数(包括二级指针的情况)
严格来说这篇文章算不上C++范围的,不过还是挂了点边,还是在自己的blog中记录一下吧. C++中使用指针是家常便饭了,也非常的好用,这也是我之所以喜欢C++的原因之一.但是在C#中就强调托管的概念了 ...
- C 语言函数参数只能传指针,不能传数组
今天被要求编写一个C/C++冒泡算法的程序,心想这还不是手到擒来的事儿,虽然最近都是用Javascript程序,很少写C/C++程序,但是好歹也用过那么多年的C语言: 首先想的是怎么让自己的代码看上去 ...
- C语言提高 (3) 第三天 二级指针的三种模型 栈上指针数组、栈上二维数组、堆上开辟空间
1 作业讲解 指针间接操作的三个必要条件 两个变量 其中一个是指针 建立关联:用一个指针指向另一个地址 * 简述sizeof和strlen的区别 strlen求字符串长度,字符数组到’\0’就结束 s ...
- C++ 有关指针作为函数参数的问题,自定义内存分配函数传递二级指针的问题
如题所示,我们主要讨论在自定义的内存分配函数中通常见到的代码如下所示: void Create(A** addr); 其中传递的参数是二级指针.为什么? 我们先看一下完整的动态内存分配函数的简单例子: ...
- C语言通过函数参数不能带出动态内存的例子。
实验结论:通过函数参数不能带出动态内存,函数参数虽然为指针,其实是在函数内部的临时变量,只是该指针的初始值是通过调用函数赋值的.C语言函数参数都是传值的. #include <stdio.h&g ...
- 在实验中观察指针——C++ 函数参数的压栈顺序
前言 好久没写东西了,突发奇想,写写函数参数的压栈顺序 先看看这个问题 https://q.cnblogs.com/q/137133/ 然后看我简化的代码,猜输出结果是多少? #include< ...
- C语言一级指针与二级指针
指针的概念 指针就是地址, 利用这个地址可以找到指定的数据 指针就是地址, 那么在使用的时候, 常常会简单的说 指针变量为指针 指针变量就是存储地址的变量 int *p1;// 申请了一个变量, 即在 ...
- c语言中如何通过二级指针来操作二维数组
通过二级指针去访问二维数组需要先给二级指针分配等同于二维数组行数的一维数组指针,然后把二维数组的每行首地址赋值给对应位置的一维指针上.之后就可以通过二维指针直接访问了. 参考代码如下,可以看具体注释辅 ...
随机推荐
- oracle 日期常用函數sysdate
SYSDATE 2 --◎ 可得到目前系統的時間 3 4 ex. 5 select sysdate from dual; 6 ...
- nrf52840蓝牙BLE5.0空中速率测试(nordic对nordic)
一.基础知识: [1]Data Length:物理层发送一包数据的最大值: [2]MTU: ATT层发送一次数据长度的最大值: [3]GAP Event Length:一个connection eve ...
- canny算子求图像边缘,edgebox那部分
过程: 1. 彩色图像转换为灰度图像 2. 对图像进行高斯模糊 3. 计算图像梯度,根据梯度计算图像边缘幅值与角度(这里其实用到了微分边缘检测算子来计算梯度幅 ...
- JAVA Collections常用方法
/* 集合框架的工具类 Collections: */ import java.util.*; class Test { public static void main(String [] args) ...
- Linux下的压缩解压缩命令
*.tar 解包:tar xvf FileName.tar 打包:tar cvf FileName.tar DirName (注:tar是打包,不是压缩!) ——————————————— *.gz ...
- 一招搞定css页面布局
如何做出漂亮的页面: 1. 多写页面,多改. 2. 多写页面,多改. 3. 多写页面,多改. 大致的思想步骤: 写页面的时候先规划好大致的分块,无论是用定位或者浮动,首先要确定要应用的场景,使用完浮动 ...
- HTML&CSS笔记001
lesson1 <!DOCTYPE html><html lang="en,zh"><!-- 告诉搜索引擎爬虫,我们的网站是关于什么内容的 --> ...
- asp.net mvc5 step by step(四)——关于Controller的ActionResult
ActionResult是控制器方法执行后返回的结果类型,控制器方法可以返回一个直接或间接从ActionResult抽象类继承的类型,如果返回的 是非ActionResult类型,控制器将会将结果转换 ...
- Mybatis Mapper动态代理方式 typeAliases 别名的使用
目录结构及配置文件与原始dao方法相比更简便 只需一个UserMapper的接口,放在一起的配置文件,配置文件中namespace的地址确定jdk动态代理的对象 <?xml version=&q ...
- 时间、时间戳相关小结 - iOS
项目中难免会与时间打交道,故此次围绕时间展开做了一些日常使用的小结;如下 code 中也是围绕一些日常开发中较为常用的点展开小的方法封装. 具体方法的使用如下: // 2019-02-21 17:30 ...