打印

哪位高手能解释一下下面的代码?

[复制链接]
2770|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gotomy|  楼主 | 2007-3-14 14:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#ifndef _VA_LIST_DEFINED
typedef char * va_list;
#define _VA_LIST_DEFINED
#endif

typedef void (* pVOID)(void);

#define va_start(ap,v) ( ap = (va_list)&v + sizeof(v) )
#define va_arg(ap,t) (((t *)ap)++[0])
#define va_end(ap)

void mprintf( char *szTypes, ... )
{
  va_list  vl;
  u8  temp;
  va_start( vl, szTypes );

   temp = va_arg( vl, unsigned char);
......
}
沙发
浪淘沙| | 2007-3-14 16:38 | 只看该作者

哈哈,这种程序不需要高手

va_start(vl, szTypes ); <—— 把szTypes当成一个指向*char数组的指针,vl将指向这个数组的第二个单元

temp = va_arg(vl, unsigned char); <—— 返回vl指向单元的内容,然后vl移动指向下一个单元

使用特权

评论回复
板凳
gotomy|  楼主 | 2007-3-15 09:27 | 只看该作者

IAR EWARM的编译器似乎无法编译这个表达式

IAR EWARM的编译器似乎无法编译这个表达式va_arg( vl, unsigned char);
报如下错误:
Error[Pe137]: expression must be a modifiable lvalue E:STR710M-V1UserSrcPROC.c 42 

使用特权

评论回复
地板
flowingray| | 2007-3-15 14:58 | 只看该作者

Re

如果是二楼所说的意思,那么++的位置显然不对。

使用特权

评论回复
5
w321| | 2007-3-16 17:38 | 只看该作者

不太好理解

  是实现什么功能里面的?   不太好理解这几个

使用特权

评论回复
6
浪淘沙| | 2007-3-16 18:36 | 只看该作者

哈哈,现在要冒充一下高手啦

3楼提出的问题:估计你是从其他平台上移植的代码,在ANSI-C的基础上,不同的编译器会有不同的扩展,如Linux上的GCC比标准的ANSI-C扩展了很多东西。

4楼的问题:++的位置没有错,如果我们把宏va_arg展开,会有这样的语句:
      temp = (((unsigned char *)vl)++[0]);
先把vl转型到unsigned char的指针,然后把这个指针当成数组并取得它的第一个单元的内容,因为++在vl的后面,所以引用完vl后再作增量运算,vl将指向下一个单元。

使用特权

评论回复
7
gyt| | 2007-3-17 13:13 | 只看该作者

厉害

浪淘沙说的是

使用特权

评论回复
8
ryansheng| | 2007-3-19 09:51 | 只看该作者

Re:

++在vl的后面固然没错,但是++前面需要一个左值(也就是lvalue),而强制类型转换(也就是unsigned char *)是不能充当左值的。

使用特权

评论回复
9
bitter| | 2007-3-26 20:36 | 只看该作者

少包含头文件

调试时经常会这样,看sprintf的函数
如果没记错的化 应该是 stdarg.h

使用特权

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

本版积分规则

43

主题

93

帖子

0

粉丝