打印

C语言问题

[复制链接]
4029|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
21ID|  楼主 | 2012-6-7 09:41 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 21ID 于 2012-6-7 09:57 编辑

数组定义:int32s  UART1SendBuf[UART1_SEND_QUEUE_LENGTH/sizeof(int32s)];
上面的定义数组长度为什么这样用?

函数调用:QueueCreate((void *)UART1SendBuf, sizeof(UART1SendBuf), NULL, (int8u (*)())Uart1WriteFull);

函数定义:int8u QueueCreate(void *Buf, int32u SizeOfBuf, int8u (* ReadEmpty)(), int8u (* WriteFull)())

#if OS_CRITICAL_METHOD == 3         
OS_CPU_SR  cpu_sr;
#endif
     DataQueue *Queue;
   
    if (Buf != NULL && SizeOfBuf >= (sizeof(DataQueue)))        /* 判断参数是否有效 */
    {
        Queue = (DataQueue *)Buf;这里为什么可以进行类型转换
        OS_ENTER_CRITICAL();
                                                                /* 初始化结构体数据 */
        Queue->MaxData = (SizeOfBuf - (int32u)(((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;
    }

相关帖子

沙发
HWM| | 2012-6-7 09:52 | 只看该作者
1)以“int32s”类型长度为其单元长定义数阻大小,自然就是那样的了。

2)参数给出的是空类指针,使用前必须的强制个类型(DataQueue在前面应该有定义)。

使用特权

评论回复
板凳
21ID|  楼主 | 2012-6-7 10:06 | 只看该作者
2# HWM

int32S是4个字节的,那么如果UART1_SEND_QUEUE_LENGTH=24,是不是数组应该像下面那样了,只有6个元素,每个元素4个字节?

QQ截图20120607100425.png (1.25 KB )

QQ截图20120607100425.png

使用特权

评论回复
地板
HWM| | 2012-6-7 10:07 | 只看该作者
是的。

使用特权

评论回复
5
21ID|  楼主 | 2012-6-7 10:09 | 只看该作者
2# HWM

对于您说的第2点,QueueCreate函数实参是UART1SendBuf,而形参在函数内部却要强制转换成DataQueue类型,还是不明白?望指点!

使用特权

评论回复
6
ayb_ice| | 2012-6-7 10:12 | 只看该作者
编译器自动计算,便于修改程序

使用特权

评论回复
7
21ID|  楼主 | 2012-6-7 10:14 | 只看该作者
6# ayb_ice

我对数组定义的理解是否正确?QueueCreat函数的不理解之处望指点!

使用特权

评论回复
8
HWM| | 2012-6-7 10:15 | 只看该作者
2# HWM  

对于您说的第2点,QueueCreate函数实参是UART1SendBuf,而形参在函数内部却要强制转换成DataQueue类型,还是不明白?望指点!
21ID 发表于 2012-6-7 10:09

“Buf”是个空类指针,使用时需要给个具体类型。

使用特权

评论回复
9
21ID|  楼主 | 2012-6-7 10:30 | 只看该作者
8# HWM

我知道使用的时候要给个具体的类型,不过为什么是DataQueue*指针类型,而不是int32u *指针类型??

使用特权

评论回复
10
21ID|  楼主 | 2012-6-7 10:35 | 只看该作者
8# HWM

我对第1点的问题理解是否正确?如果这样理解的话,我就理解不了下面的了。
希望大侠们能够指点的详细一下。

使用特权

评论回复
11
HWM| | 2012-6-7 10:38 | 只看该作者
8# HWM  

我知道使用的时候要给个具体的类型,不过为什么是DataQueue*指针类型,而不是int32u *指针类型??
21ID 发表于 2012-6-7 10:30

因为前面“Queue”的类型就是此,左右类型需一致。

使用特权

评论回复
12
ayb_ice| | 2012-6-7 10:46 | 只看该作者
你这应该是UCOSII的代码吧

因为这个是提供源代码的,并且是可配置的(可修改),编译器自动某些计算参数,这样修改时只要修改配置文件的配置,重新编译就可以用了,如果不这样做,很多地方都要修改才能正确,容易出错,最关键的还是不是所有人都会修改的。。。

使用特权

评论回复
13
21ID|  楼主 | 2012-6-7 10:47 | 只看该作者
因为前面“Queue”的类型就是此,左右类型需一致。
HWM 发表于 2012-6-7 10:38

那么为什么不在外面直接定义"Queue"类型的数组呢?现在却定义了int32s类型的数组?
定义的时候用int32s,函数调用时QueueCreate((void *)UART1SendBuf, sizeof(UART1SendBuf), NULL, (int8u (*)())Uart1WriteFull);即把UART1SendBuf转换成空类型,再在函数里面转换成DataQueue 类型,即(DataQueue *)Buf;
不理解呀,不理解!

使用特权

评论回复
14
21ID|  楼主 | 2012-6-7 11:00 | 只看该作者
你这应该是UCOSII的代码吧

因为这个是提供源代码的,并且是可配置的(可修改),编译器自动某些计算参数,这样修改时只要修改配置文件的配置,重新编译就可以用了,如果不这样做,很多地方都要修改才能正确,容易出 ...
ayb_ice 发表于 2012-6-7 10:46


这个是我买的开发板里面的程序。如果这样理解那么就是写这个代码的人,是做习惯了ucos的。然后写了个没有ucos的开发板上的程序,所以出现这样情况,函数按照ucos的风格来写的应该是没问题的,就是定义的时候有点变扭!

使用特权

评论回复
15
wookongbun| | 2012-6-7 11:03 | 只看该作者
那么为什么不在外面直接定义"Queue"类型的数组呢?现在却定义了int32s类型的数组?
定义的时候用int32s,函数调用时QueueCreate((void *)UART1SendBuf, sizeof(UART1SendBuf), NULL, (int8u (*)())Uart1WriteFull); ...
21ID 发表于 2012-6-7 10:47

这样做可以隐藏Queue类型,又能保持API的兼容性。如果作者不公布源码,楼主也不会想到他把一个数组当成Queue来用的吧?

使用特权

评论回复
16
21ID|  楼主 | 2012-6-7 11:09 | 只看该作者
那么有谁能解释一下:
“Queue->MaxData = (SizeOfBuf - (int32u)(((DataQueue *)0)->Buf)) / sizeof(QUEUE_DATA_TYPE);               /* 计算队列可以存储的数据数目 */”

使用特权

评论回复
17
wookongbun| | 2012-6-7 11:21 | 只看该作者
“把数组当Queue来用”,这样说可能不够普适。应该说是任意的一块内存都可以,像malloc之类的动态申请到的内存。
如果我没有猜错,Queue结构当中,Buf是一个void型指针,是结构中的最后一个域。这样用Queue->MaxData = (SizeOfBuf - (int32u)(((DataQueue *)0)->Buf)) / sizeof(QUEUE_DATA_TYPE);就可以得到通过形参传递过来的内存块实际上有多少空间可以用于存放数据。
原理是,假定有一个Queue结构位于0地址,而Buf域的地址就可以求出来了。这样实际是得到了Queue结构体中Buf域之前的域占了多少内存空间。通过SizeOfBuf减去这个差值,就能得到可以利用的数据空间。

使用特权

评论回复
18
慌哦不123| | 2012-6-7 11:52 | 只看该作者
第一次进这个网站,好嘛这网站

使用特权

评论回复
19
JC.Wang| | 2012-6-7 12:02 | 只看该作者
膜拜,都是C语言大神呀

使用特权

评论回复
20
21ID|  楼主 | 2012-6-7 13:37 | 只看该作者
顺利结贴,非常感谢HWM,ayb_ice,特别感谢wookongbun!

使用特权

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

本版积分规则

157

主题

912

帖子

5

粉丝