打印
[ZLG-ARM]

初用队列请教一下:如何理解?(uint32)(((DataQueue *)0)->Buf)

[复制链接]
3235|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lhzw2001|  楼主 | 2008-4-10 19:37 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
节选自queue.c文件
/************************************************************
** 函数名称: QueueCreate
** 功能描述: 初始化数据队列
** 输 入: Buf      :为队列分配的存储空间地址
**         SizeOfBuf:为队列分配的存储空间大小(字节)
**         ReadEmpty:为队列读空时处理程序
**         WriteFull:为队列写满时处理程序
** 输 出: NOT_OK:参数错误
**         QUEUE_OK:成功
** 全局变量: 无
** 调用模块: OS_ENTER_CRITICAL,OS_EXIT_CRITICAL
********************************************************/
uint8 QueueCreate(void *Buf,uint32 SizeOfBuf,uint8 (* ReadEmpty)(),uint8 (* WriteFull)())
{
    DataQueue *Queue;
    uint8 k1,k2;
    if (Buf != NULL && SizeOfBuf >= (sizeof(DataQueue)))        /* 判断参数是否有效 */
    {
        Queue = (DataQueue *)Buf;

        OS_ENTER_CRITICAL();
         /* 初始化结构体数据 */
                 
        Queue->MaxData = (SizeOfBuf - (uint32)(((DataQueue *)0)->Buf)) / sizeof(QUEUE_DATA_TYPE); 

  /* 计算队列可以存储的数据数目 */
        Queue->End = Queue->Buf + Queue->MaxData;               /* 计算数据缓冲的结束地址 */
        Queue->Out = Queue->Buf;
        Queue->In = Queue->Buf;
        Queue->NData = 0;
        Queue->ReadEmpty = ReadEmpty;
        Queue->WriteFull = WriteFull;

       OS_EXIT_CRITICAL();

        return QUEUE_OK;
    }
    else
    {
        return NOT_OK;
    }
}


---------------------------------------------------------------
请问这句要如何理解?
Queue->MaxData = (SizeOfBuf - (uint32)(((DataQueue *)0)->Buf)) / sizeof(QUEUE_DATA_TYPE);

相关定义如下:

#ifndef QUEUE_DATA_TYPE
#define QUEUE_DATA_TYPE     uint8
#endif

//-----------------------------------------------------------------------------
typedef struct {
    QUEUE_DATA_TYPE     *Out;                   /* 指向数据输出位置         */
    QUEUE_DATA_TYPE     *In;                    /* 指向数据输入位置         */
    QUEUE_DATA_TYPE     *End;                   /* 指向Buf的结束位置        */
    uint16              NData;                  /* 队列中数据个数           */
    uint16              MaxData;                /* 队列中允许存储的数据个数 */
    
    uint8               (* ReadEmpty)();        /* 读空处理函数             */
    uint8               (* WriteFull)();        /* 写满处理函数             */
    QUEUE_DATA_TYPE     Buf[1];                 /* 存储数据的空间           */
} DataQueue;

相关帖子

沙发
赖皮| | 2008-4-11 10:00 | 只看该作者

结构变量相应数据的地址偏移量

使用特权

评论回复
板凳
lhzw2001|  楼主 | 2008-4-11 18:17 | 只看该作者

((DataQueue *)0)表示结构体自身,是这样吧!

((DataQueue *)0)->Buf 也就是说,

((DataQueue *)0)表示结构体自身,是这样吧!

使用特权

评论回复
地板
zlgarm| | 2008-4-11 20:07 | 只看该作者

BUF问题回复

lhzw2001  ,您好:

这是一个非常巧妙的方法,定义起始地址为0,指向BUF空间首地址,方便下面语句计算空间大小。

zlgarm_Li Baihua

使用特权

评论回复
5
mohanwei| | 2008-4-11 20:22 | 只看该作者

附议

(DataQueue *)表示后面的是一个“DataQueue”指针
后面的是0,那么表示该指针的值是0,那么这个“DataQueue”存放的地址就是0。
……
这样计算成员的偏移量就方便多了

使用特权

评论回复
6
ATmega32L| | 2008-4-11 20:59 | 只看该作者

使用特权

评论回复
7
lhzw2001|  楼主 | 2008-4-12 21:54 | 只看该作者

多谢各位讲解,俺想通了!

使用特权

评论回复
8
平常人| | 2008-4-12 22:06 | 只看该作者

虽然巧妙,但可读性不好

Queue->MaxData = (SizeOfBuf - ((uint32)&Queue->Buf[0] - (uint32)&Queue->Out)) / sizeof(QUEUE_DATA_TYPE);

这样写多数人都能看懂,比之前的要好看。

使用特权

评论回复
9
lhzw2001|  楼主 | 2008-4-13 18:49 | 只看该作者

确实是好懂多了!!!

使用特权

评论回复
10
15859892563| | 2020-1-14 11:40 | 只看该作者
1、不使用sizeof去取结构体变量的大小而是用这种方法应该是为了不多定义一个结构体变量或者程序的兼容不想用stdio.h文件。
2、(DataQueue *)0把地址0 定义成结构体类型,可以减少变量,同时减少计算地址长度。
3、->Buf数组名就是地址,指向成员数组的地址是结构体最后一字节。
所以 (u32)(((DataQueue *)0)->Buf)/  sizeof(QUEUE_DATA_TYPE)是结构体的长度。

使用特权

评论回复
11
15859892563| | 2020-1-14 13:59 | 只看该作者
好像这个MaxData 最大64K,不知道要不要做超出判断处理

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

337

帖子

0

粉丝