C可变参数的使用

1、参数可变的宏

先看一个例子
#include <stdio.h>
#define debug(fmt,...) printf(fmt,__VA_ARGS__)
void main()
{
	debug("Test %d\n",1);
}
输出结果为 : Test 1    
    这里,‘ … ’指可变参数。这类宏在被调用时,它(这里指‘ … ’)被表示成零个或多个符号,包括里面的逗号,一直到到右括弧结束为止。当被调用时,在宏体( macro body )中,那些符号序列集合将代替里面的__VA_ARGS__ 标识符。    在标准 C 里,你不能省略可变参数,但是你却可以给它传递一个空的参数。例如,下面的宏调用在 ISO C 里是非法的,因为字符串后面没有逗号:
debug("Test \n"); //编译不通过   
为了解决这个问题, 使用一个特殊的‘ ## ’操作。书写格式为:
#define debug(fmt,...) printf(fmt,__VA_ARGS__)
完整的使用例子如下:
#include <stdio.h>

#define LOGLEVEL 1

#define debug(fmt,...) printf(fmt,##__VA_ARGS__)

#define debugLevel(loglevel,fmt,...)  \
{\
	if(loglevel >= LOGLEVEL)\
		debug(fmt,##__VA_ARGS__);\
}
void main()
{
	debug("Test \n");
	debugLevel(1,"Test level 1\n");
	debugLevel(1,"Test level 1 %d\n",100);
	debugLevel(0,"Test level 0\n");
}
结果:
Test 
Test level 1

Test level 1 100

例2:

#include <stdio.h>

#define DEBUG_PRINT

#define debug(fmt,...) printf(fmt,##__VA_ARGS__)

#ifdef DEBUG_PRINT
	#define debugprint(fmt,...)  \
		debug(fmt,##__VA_ARGS__)
#else
	#define debugprint(fmt,...)
#endif
void main()
{
	debug("Test \n");
	debugprint("Test\n");
	debugprint("Test 1 %d\n",100);
}

2、函数参数使用可变参数

C语言可变参数通过三个宏(va_start、va_end、va_arg)和一个类型(va_list)实现的,

va_list:
功能:用来保存宏va_start、va_arg和va_end所需信息的一种类型。为了访问变长参数列表中的参数,必须声明va_list类型的一个对象;

void va_start ( va_list ap, paramN );
功能:访问变长参数列表中的参数之前使用的宏,它初始化用va_list声明的对象,初始化结果供宏va_arg和va_end使用;

type va_arg ( va_list ap, type );
功能:返回下一个参数的值

void va_end ( va_list ap );
功能:该宏使程序能够从变长参数列表用宏va_start引用的函数中正常返回。

va在这里是variable-argument(可变参数)的意思. 
这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.

好了,综合上面3个宏和一个类型可以猜出如何实现C语言可变长参数函数:用 va_start 获取参数列表(的地址)存储到 ap 中,用 va_arg 逐个获取值,最后用 va_end 将 ap 置空。

#include <stdio.h>;
#include <string.h>;
#include <stdarg.h>;

/* ANSI标准形式的声明方式,括号内的省略号表示可选参数 */

int demo(char *msg, ... )
{
    va_list argp;                   /* 定义保存函数参数的结构 */
    int argno = 0;                  /* 纪录参数个数 */
    char *para;                     /* 存放取出的字符串参数 */

    va_start( argp, msg ); /* argp指向传入的第一个可选参数,   msg是最后一个确定的参数 */

    while (1)
    {
        para = va_arg( argp, char *);                 /*    取出当前的参数,类型为char *. */
        if ( strcmp( para, "/0") == 0 )
                                                      /* 采用空串指示参数输入结束 */
            break;
        printf("Parameter #%d is: %s\n", argno, para);
        argno++;
    }
    va_end( argp );                                   /* 将argp置为NULL */
    return 0;
}

void main( void )
{
	demo("DEMO", "This", "is", "a", "demo!" ,"333333", "/0");
}
需要注意的地方:
va_arg宏的第2个参数不能被指定为char、short或者float类型。
因为char和short类型的参数会被转换为int类型,而float类型的参数会被转换为double类型 

3、C语言可变参数个数的确定

在网上查到的,没看懂,留个链接http://biancheng.dnbcw.info/c/236623.html

本文转载整理自网络,侵权请告知!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值