论坛摘选(省略参数,va_List,_vsntprintf )等
来源:互联网 发布:mac如何卸载xlplayer 编辑:程序博客网 时间:2024/06/02 12:46
va_start执行后pArgList指向szFormat后面的第一个可变参数,但没有用va_arg取得其值(包括第二个可变参数),为何可以直接调用_vsntprintf ( szBuffer, sizeof (szBuffer) / sizeof (TCHAR),
szFormat, pArgList)?
你在va_start执行后pArgList的值,即地址已经确定下来了啊
其实在头文件中
typedef char * va_list; //va_list为字符型指针
这么定义的,
而你接下来是要对字符串的处理,做一个输出,所以只要知道一个首地址和长度就可以了
信息已经足够
int _vsnprintf( char *buffer, size_t count, const char *format, va_list argptr );
其中count 为buffer所允许的最大容量
sizeof (szBuffer) / sizeof (TCHAR), //计算最大容量,如果为UNICOLE则sizeof(TCHAR)=2,否则等于0;
------------------------------------------------------------------------------------------------------------------------------------------------------
首地址是已经确认了,是在szFormat之后,长度怎么确定了呢,本例中szFormat后面的不是char *,是两个int 变量cxScreen, cyScreen ,按照定义 pArgList 是va_list,也即是 char * ,是否可以这样理解?
变参函数的 变参数, 就是只提供一个首地址,正如你所说, 长度怎么确定了呢?
如果长度不确定,我又该如何来做呢?
所以就会有格式控制符,体现在这里就是 szFormat, 这也是一个字符串,根据它的内容来解析你的pArgList
常用一点的,比如printf("%s%d", "abc",34);
典型的变参函数,就是通过"%s%d",相当这里的szFormat, 来输出的,
内存里会有一些值,但这些值是什么类型,每个占多少字节,就是有szFormat来控制拉
比如"%s",会找到'/0'止, %d就去找4个字节
不知道你明白了没有
-------------------------------------------------------------------------------------------------------------------------------------------------
哦,明白了,是否可以这样说,只要有格式控制 ,就可以不用va_arg啦,
有那么点意思
看问题要看本质
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
你可以看到va_arg就是通过格式控制来实现的
所以如果你自己提供了格式控制,就不需要它来做了
---------------------------------------------------------------------------------------------------------------------------------------------------
变参函数的核心不是格式,这个仅仅是变参的使用。
可变参数是在直接操纵栈,只要你有办法把你的栈里面的内容通知变参函数,就可以实现可变参数的功能。标准库的printf函数族利用了变参函数来实现格式化的输出,但这个仅仅是变参函数的一种使用方法而已。早期(K&R时期)的printf函数族并没有以...来声明printf的原型,而是把括号留空,利用某些trick来完成这项工作。到了C标准化以后,出现了...作为变参的用法,此时printf的原型就成了
int printf(const char*, ...);
提供了对格式类型的检查(譬如你这样调用printf:printf(1); 这样就不被允许了,但是早期的printf是可以这么干的)
给你个可变参数的例子吧……
#include <stdio.h>
void func(int argc, ...)
//argc保存了参数的个数
//...里面是参数
{
int i, *ptr = &argc + 1;
for(i = 0; i < argc; i++)
{
printf("%d/n", ptr[i]);
}
}
int main(int argc, char* argv[])
{
func(2, 3, 4);
}
以上代码通过gcc 3.4.2的编译……
另外顺带说一句,gcc里面-Wformat可以通知gcc对printf函数族进行完整的类型检查(编译器会解析你给出的格式化字符串),如下代码就会被检测到有问题
int i;
printf("%s", i);
- 论坛摘选(省略参数,va_List,_vsntprintf )等
- 可变参数(va_list)
- va_list、va_start、_vsntprintf、va_end用法示例(以备后用)
- va_start、va_end、va_list等可变参数的使用
- java中的省略参数
- java中的省略参数
- va_list可变参数传递
- va_list 可变参数变量
- va_list 可变参数
- 可变参数 用法 va_list
- 可变参数用法 va_list
- va_list 可变参数实例
- 【可变参数 VA_LIST】
- 可变参数va_list
- va_list 可变参数
- 可变参数列表 va_list
- va_list、va_start、va_arg、va_end等利用宏定义实现可变参数
- 可变参数函数printf的实现(不使用va_list等内置宏定义)
- linux's coredump storage
- 国美、海尔、第三方网站——揭秘家电B2C三大势力
- 零基础制作【武林外传】辅助工具(一)
- [转载]LCC编译器的源程序分析(33)break语句
- 零基础制作【武林外传】辅助工具(二)
- 论坛摘选(省略参数,va_List,_vsntprintf )等
- 零基础制作【武林外传】辅助工具(三)
- 比尔盖茨致青年的黄金准则(双语)
- PreparedStatement中使用模糊查询
- debug iptables script
- 《对弈程序基本技术》专题
- my vimrc
- Google搜索技巧
- 一幅诡异的油画“2008-北京”