lhzw2001 发表于 2008-4-10 19:37

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

节选自queue.c文件<br />/************************************************************<br />**&nbsp;函数名称:&nbsp;QueueCreate<br />**&nbsp;功能描述:&nbsp;初始化数据队列<br />**&nbsp;输 入:&nbsp;Buf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:为队列分配的存储空间地址<br />**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SizeOfBuf:为队列分配的存储空间大小(字节)<br />**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadEmpty:为队列读空时处理程序<br />**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteFull:为队列写满时处理程序<br />**&nbsp;输 出:&nbsp;NOT_OK:参数错误<br />**&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;QUEUE_OK:成功<br />**&nbsp;全局变量:&nbsp;无<br />**&nbsp;调用模块:&nbsp;OS_ENTER_CRITICAL,OS_EXIT_CRITICAL<br />********************************************************/<br />uint8&nbsp;QueueCreate(void&nbsp;*Buf,uint32&nbsp;SizeOfBuf,uint8&nbsp;(*&nbsp;ReadEmpty)(),uint8&nbsp;(*&nbsp;WriteFull)())<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;DataQueue&nbsp;*Queue;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;k1,k2;<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Buf&nbsp;!=&nbsp;NULL&nbsp;&&&nbsp;SizeOfBuf&nbsp;&gt=&nbsp;(sizeof(DataQueue)))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;判断参数是否有效&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue&nbsp;=&nbsp;(DataQueue&nbsp;*)Buf;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_ENTER_CRITICAL();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;初始化结构体数据&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtMaxData&nbsp;=&nbsp;(SizeOfBuf&nbsp;-&nbsp;(uint32)(((DataQueue&nbsp;*)0)-&gtBuf))&nbsp;/&nbsp;sizeof(QUEUE_DATA_TYPE);&nbsp;<br /><br />&nbsp;&nbsp;/*&nbsp;计算队列可以存储的数据数目&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtEnd&nbsp;=&nbsp;Queue-&gtBuf&nbsp;+&nbsp;Queue-&gtMaxData;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;计算数据缓冲的结束地址&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtOut&nbsp;=&nbsp;Queue-&gtBuf;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtIn&nbsp;=&nbsp;Queue-&gtBuf;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtNData&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtReadEmpty&nbsp;=&nbsp;ReadEmpty;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue-&gtWriteFull&nbsp;=&nbsp;WriteFull;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OS_EXIT_CRITICAL();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;QUEUE_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NOT_OK;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><br />---------------------------------------------------------------<br />请问这句要如何理解?<br />Queue-&gtMaxData&nbsp;=&nbsp;(SizeOfBuf&nbsp;-&nbsp;(uint32)(((DataQueue&nbsp;*)0)-&gtBuf))&nbsp;/&nbsp;sizeof(QUEUE_DATA_TYPE);<br /><br />相关定义如下:<br /><br />#ifndef&nbsp;QUEUE_DATA_TYPE<br />#define&nbsp;QUEUE_DATA_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8<br />#endif<br /><br />//-----------------------------------------------------------------------------<br />typedef&nbsp;struct&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;QUEUE_DATA_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*Out;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;指向数据输出位置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;QUEUE_DATA_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*In;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;指向数据输入位置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;QUEUE_DATA_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*End;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;指向Buf的结束位置&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NData;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;队列中数据个数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;uint16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxData;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;队列中允许存储的数据个数&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;ReadEmpty)();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;读空处理函数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;uint8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*&nbsp;WriteFull)();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;写满处理函数&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />&nbsp;&nbsp;&nbsp;&nbsp;QUEUE_DATA_TYPE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Buf;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;存储数据的空间&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br />}&nbsp;DataQueue;<br />

赖皮 发表于 2008-4-11 10:00

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

lhzw2001 发表于 2008-4-11 18:17

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

((DataQueue&nbsp;*)0)-&gtBuf&nbsp;也就是说,<br /><br />((DataQueue&nbsp;*)0)表示结构体自身,是这样吧!<br /><br />

zlgarm 发表于 2008-4-11 20:07

BUF问题回复

lhzw2001&nbsp;&nbsp;,您好:<br /><br />这是一个非常巧妙的方法,定义起始地址为0,指向BUF空间首地址,方便下面语句计算空间大小。<br /><br />zlgarm_Li&nbsp;Baihua

mohanwei 发表于 2008-4-11 20:22

附议

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

ATmega32L 发表于 2008-4-11 20:59

lhzw2001 发表于 2008-4-12 21:54

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

平常人 发表于 2008-4-12 22:06

虽然巧妙,但可读性不好

Queue-&gtMaxData&nbsp;=&nbsp;(SizeOfBuf&nbsp;-&nbsp;((uint32)&Queue-&gtBuf&nbsp;-&nbsp;(uint32)&Queue-&gtOut))&nbsp;/&nbsp;sizeof(QUEUE_DATA_TYPE);<br /><br />这样写多数人都能看懂,比之前的要好看。

lhzw2001 发表于 2008-4-13 18:49

确实是好懂多了!!!

15859892563 发表于 2020-1-14 11:40

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

15859892563 发表于 2020-1-14 13:59

好像这个MaxData 最大64K,不知道要不要做超出判断处理
页: [1]
查看完整版本: 初用队列请教一下:如何理解?(uint32)(((DataQueue *)0)->Buf)