windows学习笔记2——va_list,va_start,va_end,va_arg的使用
2013-12-08 19:07
288 查看
有时我们需要编写这样的函数:函数的参数个数不确定,就像printf(const char* szFormat, ...);一样。这时候,如何方便地处理这些变参是一件需要仔细考虑的问题,例如我们需要在函数中判断用户输入的参数中是否有等于0的实参,你该怎么做?
幸运的时,大师级的先驱们已经为我们做好了,下面让我们一起来研究一下va_arg, va_end,va_start等相关的用法吧!<参看MSDN>
1、需要的头文件和库文件
ANSI 版(windows下):
<stdio.h>和<stdarg.h>
UINX 版
<varargs.h>
库文件:
单线程静态库:LIBC.LIB
多线程静态库:LIBCMT.LIB
MSVCRT.DLL的导入库:MSVCRT.LIB
2、鉴于学习的window,暂时不考虑UINX版
在stdarg.h中:关于va_list的定义如下:
![](http://img.blog.csdn.net/20131208185641218?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hpYW95dXNoZW5nMjAxMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
关于va_start, va_end, va_arg的定义如下:
![](http://img.blog.csdn.net/20131208185739921?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb3hpYW95dXNoZW5nMjAxMg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
3、MSDN中关于va_start,va_end,va_arg的描述
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, prev_param);(ANSI版)
type 为接收的参数的类型
arg_ptr 为指向参数列表的指针
prev_param 为 原始参数列中最前面的(第一个)参数。
va_start宏:设置参数列表指针arg_ptr指向传递给函数参数表的第一个原始参数(prev_param)
va_end宏:在所有参数被检索完成后,va_end重置指针arg_ptr指向NULL
va_arg宏:接收arg_ptr指向的type类型的变量,同时使arg_ptr加一,指向参数列表的下一个变量,它是通过宏中的第二个参数type来确定下一个变量的开始位置,va_arg可以在函数中使用任意多次来接收参数列表中的参数。
4、用例:
#include <stdio.h>
#define ANSI
#ifdef ANSI
#include <stdarg.h>
//声明一个变参函数
int average(int first, ...);
#endif
int average(int first, ...)
{
int count =0, sum =0, i= first;
va_list m_args;//定义自己的参数列表指针
va_start(m_args, first);//使参数列表指针指向输入参数表的第一个//参数
while(i != -1)
{
sum+=i;
count++;
i = va_arg(m_args, int);//取出当前参数
}
va_end(m_args);//置空列表指针,以便下一次使用
return( sum?(sum/count):0);
}
int main(int crgc, char** argv)
{
printf("%d", average(1, 2, -1));
printf("%d", average(1, 2, 3, -1));
printf("%d", average(1, 2, 3, 4, -1));
}
幸运的时,大师级的先驱们已经为我们做好了,下面让我们一起来研究一下va_arg, va_end,va_start等相关的用法吧!<参看MSDN>
1、需要的头文件和库文件
ANSI 版(windows下):
<stdio.h>和<stdarg.h>
UINX 版
<varargs.h>
库文件:
单线程静态库:LIBC.LIB
多线程静态库:LIBCMT.LIB
MSVCRT.DLL的导入库:MSVCRT.LIB
2、鉴于学习的window,暂时不考虑UINX版
在stdarg.h中:关于va_list的定义如下:
关于va_start, va_end, va_arg的定义如下:
3、MSDN中关于va_start,va_end,va_arg的描述
type va_arg(va_list arg_ptr, type);
void va_end(va_list arg_ptr);
void va_start(va_list arg_ptr, prev_param);(ANSI版)
type 为接收的参数的类型
arg_ptr 为指向参数列表的指针
prev_param 为 原始参数列中最前面的(第一个)参数。
va_start宏:设置参数列表指针arg_ptr指向传递给函数参数表的第一个原始参数(prev_param)
va_end宏:在所有参数被检索完成后,va_end重置指针arg_ptr指向NULL
va_arg宏:接收arg_ptr指向的type类型的变量,同时使arg_ptr加一,指向参数列表的下一个变量,它是通过宏中的第二个参数type来确定下一个变量的开始位置,va_arg可以在函数中使用任意多次来接收参数列表中的参数。
4、用例:
#include <stdio.h>
#define ANSI
#ifdef ANSI
#include <stdarg.h>
//声明一个变参函数
int average(int first, ...);
#endif
int average(int first, ...)
{
int count =0, sum =0, i= first;
va_list m_args;//定义自己的参数列表指针
va_start(m_args, first);//使参数列表指针指向输入参数表的第一个//参数
while(i != -1)
{
sum+=i;
count++;
i = va_arg(m_args, int);//取出当前参数
}
va_end(m_args);//置空列表指针,以便下一次使用
return( sum?(sum/count):0);
}
int main(int crgc, char** argv)
{
printf("%d", average(1, 2, -1));
printf("%d", average(1, 2, 3, -1));
printf("%d", average(1, 2, 3, 4, -1));
}
相关文章推荐
- va_list、va_start、va_arg、va_end的原理与使用
- 不定长参数处理方法--va_list、va_start、va_arg、va_end的原理与使用
- va_list、va_start、va_arg、va_end的原理与使用
- 理解可变参数va_list、va_start、va_arg、va_end原理及使用方法
- va_start、va_arg、va_end、va_list的使用
- 《C语言接口与实现》实验——可变参数表的使用(va_list, va_start, va_arg, va_end)
- 理解va_list、va_start、va_arg、va_end原理既使用方法
- 理解可变参数va_list、va_start、va_arg、va_end原理及使用方法
- 理解可变参数va_list、va_start、va_arg、va_end原理及使用方法
- va_list、va_start、va_arg、va_end的原理与使用
- C/C++中va_list,va_start,va_arg,va_end的使用和原理
- 理解va_list、va_start、va_arg、va_end原理及使用方法
- va_list,va_start,va_arg,va_copy和va_end的使用
- 转:va_list、va_start、va_arg、va_end的原理与使用
- va_list、va_start、va_arg、va_end的原理与使用
- 理解可变参数va_list、va_start、va_arg、va_end原理及使用方法
- va_list、va_start、va_arg、va_end的原理与使用
- printf函数中“va_list 、va_start、 va_arg、 va_end” 使用说明
- va_list、va_start、va_arg、va_end的原理与使用
- va_list、va_start、va_arg、va_end的原理与使用