VC msdn其中一个函数的作用

tuyang120428941 2010-04-12 11:25:14
这个函数的使用方法 int vsprintf( char *buffer, const char *format, va_list argptr );

void input(char *fmt,...)
{char temp[200];
va_list args;
va_start(args,fmt);
vsprintf(temp, fmt, args);//这里第二个参数不是格式化声明么,怎么这里直接以一个变量名代替了,谁能解释下
va_end(args);
}

麻烦你们能给我解释下 TEMP里面最后是以什么样的格式接收了这些参数
...全文
68 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
wltg2001 2010-04-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tuyang120428941 的回复:]
引用 1 楼 wltg2001 的回复:
vsprintf(temp, fmt, args);//这里第二个参数不是格式化声明么,怎么这里直接以一个变量名代替了,谁能解释下
========
可以啊,所谓格式化声明其实也就是一个字符串,你用常量的形式写可以,写在一个字符串数组里面,然后用这个字符串变量当然也可以


能举个例子么?我比较菜
[/Quote]
给个例子吧:
#include <stdarg.h>
  char buffer[80];
  int vspf(char *fmt, ...)
  {
  va_list argptr;
  int cnt;
  va_start(argptr, fmt);
  cnt = vsprintf(buffer, fmt, argptr);
  va_end(argptr);
  return(cnt);
  }
  int main(void)
  {
  int inumber = 30;
  float fnumber = 90.0;
  char string[4] = "abc";
  vspf("%d %f %s", inumber, fnumber, string);
  printf("%s\n", buffer);
  return 0;
  }
tuyang120428941 2010-04-13
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wltg2001 的回复:]
vsprintf(temp, fmt, args);//这里第二个参数不是格式化声明么,怎么这里直接以一个变量名代替了,谁能解释下
========
可以啊,所谓格式化声明其实也就是一个字符串,你用常量的形式写可以,写在一个字符串数组里面,然后用这个字符串变量当然也可以
[/Quote]

能举个例子么?我比较菜
finder_zhang 2010-04-13
  • 打赏
  • 举报
回复
MSDN上说,类似printf的,有几对函数,一双一双的,功能是一样,但一个是接收可变参数,另一个是接收参数表的指针.
printf("%c %c %c\n",'a','b','c'); 这个函数的输出是 a b c ,相信大家不会陌生了.
照说,vprintf就是接收参数表了,这个参数表,又是怎么一回事呢?
int vprintf( const char *format, va_list argptr );函数的定义是这样的
而 va_list 是 char* 类型.
想当然地,我写出了下面的代码.编译通过,运行出错.
char chArr[3] = {'a','b','c'}; //把参数放到数组中
vprintf("%c %c %c\n",chArr); //传参数的数组

后来我才知道原来这里的参数数组va_list argptr,并不是简单的 char chArr[],而是放在栈里面的一个一个的chArr数组的元素.
调用函数时,压在栈里的参数,是4字节对齐的.第一个参数就算只有1字节,也占了4字节.
而char chArr[]的数组,元素间是一个一个挨着放的.

然后我把代码改为如下
unsigned int ch[] = {'a','b','c'}; //每个元素都占4字节
vprintf("%c %c %c\n",(char*)ch);
编译通过,运行成功了,结果与
printf("%c %c %c\n",'a','b','c');是一样的.
原来与 printf 对应的 vprintf 函数,他最后一个参数char*,并不是要取一个char[],而是一个一个在栈里的4字节对齐的数据.

那些 va_xxx 又是怎么回事呢?
va_list args 其实是char* args,定义一个 char* 变量准备传给 v xxxx f 函数使用的.
va_start(args,fmt)
我们可以找到
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
的定义,要了解这个,首先要知道函数的参数到底是如何放置的

我写了一个小的测试代码
void ParamAddr(char* pCh,char ch,short s,int i)
{
printf("pChAddr = %x\n",&pCh);
printf("chAddr = %x\n",&ch);
printf("s Addr = %x\n",&s);
printf("i Addr = %x\n",&i);
}
输出一看,就可以发现,&i 在最高地址.
然后地址一直减少,&pCh,在最高地址.

从上面的程序知道了参数是从左到右,从低到高排列,每参数最少占4字节之后.va_start就好理解了.
va_start(args,fmt) -->> args = (LPSTR)&fmt + _INTSIZEOF(fmt)[这个意思是4字节对齐的fmt大小]
意思就是args 等于 fmt 的地址 再加上 fmt 占用的大小,那么 args 就会指着 fmt 的下一个参数的地址了.
fmt的下一个参数的地址,指的正是可变参数在栈中的地址.这个地址传给
vprintf 的最后一个参数,就像我的这个代码一样.
unsigned int ch[] = {'a','b','c'};
vprintf("%c %c %c\n",(char*)ch);
就刚好符合 vprintf 的要求了.

而va_end(args) 只是将该变量清0,因为他指着了函数参数的最右边参数的结尾的下一个字节处,
已经不需要再使用,将其清0,免得有误动作.
Eleven 2010-04-12
  • 打赏
  • 举报
回复
msdn里不是有很好的解释吗?
wltg2001 2010-04-12
  • 打赏
  • 举报
回复
vsprintf(temp, fmt, args);//这里第二个参数不是格式化声明么,怎么这里直接以一个变量名代替了,谁能解释下
========
可以啊,所谓格式化声明其实也就是一个字符串,你用常量的形式写可以,写在一个字符串数组里面,然后用这个字符串变量当然也可以

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧