vprintf 与可变参数
来源:互联网 发布:淘宝上的老王手办 编辑:程序博客网 时间:2024/04/29 20:11
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); //传参数的数组
我一直不知道我错在哪里.直到今天看到CSDN上有朋友问一个可变参的问题,我才知道了答案.
他问的是
这个函数的使用方法 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);
}
我在思考这个问题时才知道原来这里的参数数组va_list argptr,并不是简单的 char chArr[],
而是放在栈里面的一个一个的chArr数组的元素.
调用函数时,压在栈里的参数,是4字节对齐的.第一个参数就算只有1字节,也占了4字节.
而char chArr[]的数组,元素间是一个一个挨着放的.
然后我把代码改为如下
unsigned int ch[] = {'a','b','c'};
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 的要求了.
- vprintf 与可变参数
- linux 可变参数va_* 和vprintf的使用
- 可变参数与printf
- Foreach与可变参数
- 数组与可变参数
- vprintf
- vprintf
- 自动装箱与可变参数
- java枚举与可变参数
- 可变参数、重写与重载
- CPP多线程与可变参数
- 可变参数宏与枚举
- C/C++可变参数与默认参数
- 关于PHP可变参数与缺省参数
- python中的参数定义与可变参数
- 可变参数与参数进栈顺序
- ##的意思与可变参数宏
- 条件编译debug与可变参数宏
- Ubuntu9.04 配置gcc g++
- 【转】各类手机开发平台介绍
- HDFS写文件解析
- 分不够啊
- 程序中的乱码问题
- vprintf 与可变参数
- 单点登录(Single Sign On , 简称 SSO )
- Sliverlight change the scene
- H桥电机驱动原理与应用
- 使用SQL语句查找主键
- unix下查看主机名
- 初始化指针
- Java多线程编程详解
- delphi保存读取utf-8的文本文件