实现自己的不定参数的函数

不定参数在一些特殊场合下是很有用的,例如在字符串的格式化合成,像printf()函数、日志输出等场合都很容易想到这样的结构。

其实,这种方法在C语言里就已经存在了,也不是什么新奇特的东西,一般要实现这样的功能,需要以下几个函数/类型组成:

va_list 、va_start、va_avg、va_end

头文件:stdarg.h

 

先来看两个例子:

例1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
uint GetSum(uint nD1,...)
{
     va_list  st;
     va_start (st, nD1);
     uint total = nD1;
     uint tmp;
     while ((tmp =  va_arg (st, uint)) != 0)
     {
         total += tmp;
     }
     va_end (st);
 
     return  total;
}

例2:

复制代码
double sum_series(int num, ...)  
{  
    double sum = 0.0, t;  
    va_list argptr;  
    va_start(argptr, num);//初始化变元指针  
    while (num--)  
    {  
        t = va_arg(argptr, double);  
        sum = sum + t;  
    }  
    va_end(argptr);  
    return sum;  
}  
复制代码

 

PS:以上两个例子是摘自网上,我想比较简单,大家百度一下也是一大堆。

先来说说,这两种方式的缺点吧:

例1,需要输入一个“0”作为结束符,而且中间参数中不能出现0;这个条件限制,另外输入的参数必须是同一种类型,不是非常灵活。

例2,需要预先输入参数的个数,这里也有严重缺陷的,因为如果输出的num大于实际后面的参数个数的话,就越界了;另外参数增加就要修改num的输入值,这样也不方便;输入的参数必须是同一种类型,不是非常灵活。

 

问题,printf可是没有要求输入参数的个数以及类型必须统一,这样的要求哦?

的确,printf很灵活,没有那么限制,那么如何实现呢?难道va_arg存在特殊判断可以确定最后一个参数?

 

遗憾的是,va_arg是不知道最后一个参数的,除非像例子里一样,告之个数或特殊参数为结尾。。。

那么printf怎么做到的?

 

猜测,printf的第一个参数为 char* ,是个字符串,而且输入的时候,有参数的时候必须以“%”为开头,

那么,问题就简单了,我们先遍历一遍,看看%出现几次(排除%%),不就是知道了个数了。

 

然后在解析下%后面的s d什么的,就不是问题了。。。。

 

最后再给个例子

复制代码
void DEBUG_LOG(uint nLogID,char *strFmt,...)
{
    char strLog[2048];
    //查找“%”
    va_list lsID;
    va_start(lsID, strFmt);
    vsprintf(strLog, strFmt, lsID);
    va_end(lsID);

    DEBUG_LOG00(nLogID,strLog);
}
posted on 2017-07-29 14:24 顾小刚 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/winafa/p/7255826.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值