详细介绍关于宏va_list ,va_start ,va_arg ,va_end的使用

目录

简介

va_start宏

va_arg宏

va_end宏

实例:利用va_arg打印

实例:打印不同可变参数类型


简介

之前在查阅资料时一直没有找到一个完整的介绍这些宏的文章,故根据自己的理解整理了一下。va_list ,va_start ,va_arg ,va_end是C中stdarg.h头文件里面的宏,它们主要用于配合处理一组可变参数,这组可变参数的数量无需提前确定,用起来十分灵活。

typedef char *va_list;

va_start宏

va_start(list, param1)   list: va_list类型的指针  param1: 最后一个固定参数(若有多个固定参数)

#define va_start(list,param1)   ( list = (va_list)&param1+ sizeof(param1) )

看它在定义的时候,list = (va_list)&param1+ sizeof(param1),其中的list本来是va_list类型指针,param1是最后一个固定参数的地址,经过这步操作后将list成功指向了第一个可变参数。             如图:

va_arg宏

弄懂这个宏不难                                                                                                                                  va_arg(list, mode)  list: va_list类型的变量  mode: 要返回的参数类型 返回值:返回当前指针指向的可变参数(第一次为第一个可变参数) 经过多次验证,如果使用这个宏可变参数列表中类型必须相同,因为mode的参数类型不可变,返回后将指针指向下一个参数

#define va_arg(list,mode)   ( (mode *) ( list += sizeof(mode) ) )[-1]

观察这个宏定义就明白了,在执行va_start这个宏后就已经将指针指向了第一个可变参数,这时执行list += sizeof(mode)就会将指针指向下一个可变参数。                                                                  如图:    

va_end宏

va_end(list)   list: va_list类型的变量                                                                                                 执行该宏可以清空可变参数列表

实例:利用va_arg打印

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
void var_test(char *format, ...)
{
    va_list list;
    va_start(list,format);
    char *ch;
    while(1)
    {
         ch = va_arg(list, char *);
 
         if(strcmp(ch,"") == 0)
         {    
               printf("\n");
               break;
         }
         printf("%s ",ch);
     }
     va_end(list);
}
int main()
{
    var_test("test","this","is","a","test","");
    return 0;
}

  

 这里用了va_arg宏,第一个可变参数为“this”,所以从“this”开始打印,可变参数类型也相同。

 

实例:打印不同可变参数类型

那么如何打印不同的可变参数类型呢,需要用到vprintf。

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

 
int myprintf(char *format, ...)
{
    va_list ap;
    int n;
    va_start(ap, format); 
    n = vprintf(format, ap);
    va_end(ap);
    return n;  
}
int main()
{
    
    int n = myprintf("%s %s %d %s %s\n","I","am",22,"years","old");
    printf("%d",n);
    return 0;
}

 

 在这个历程中,实现了不同类型输出,但没有使用va_arg这个宏,因为这个宏里面mode参数的类型不可变,所以不能用va_arg来控制指针偏移,如果想利用va_list来输出不同类型的参数时,需要如此做。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值