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

不定参数在一些特殊场合下是很有用的,例如在字符串的格式化合成,像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);
}
时间: 2024-11-05 11:46:12

实现自己的不定参数的函数的相关文章

php写一个不定参数的函数

function add() { $num=func_num_args(); $list=func_get_args(); $renum=0; for($i=0;$i<$num;$i++) { $renum+=$list[$i]; } return $renum; } func_num_args();//获取输入参数的的个数 func_get_args();//获取输入参数的每个值 func_get_arg ( int $arg_num )//获取输入参数某个特定位置的值

c++不定参数函数

不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多.除了格式化输出之外,我实在没看到多少应用.主要原因是这种技术比较麻烦,副作用也比较多,而一般情况下重载函数也足以替换它.尽管如此,既然大家对它比较感兴趣,我就简单总结一下它的使用和需要注意的常见问题. 原理 刚学C语言的时候,一般人都会首先接触printf函数.通过这个函数,你可以打印不定个数的变量到屏幕,如: printf("%d", 3);printf("%d,%d",3,4)

不定参数的应用

不定参数当年做为C/C++语言一个特长被很多人推崇,但是实际上这种技术并没有应用很多.除了格式化输出之外,我实在没看到多少应用.主要原因是这种技术比较麻烦,副作用也比较多,而一般情况下重载函数也足以替换它.尽管如此,既然大家对它比较感兴趣,我就简单总结一下它的使用和需要注意的常见问题.原理:刚学C语言的时候,一般人都会首先接触printf函数.通过这个函数,你可以打印不定个数的变量到屏幕,如:printf("%d", 3);printf("%d,%d",3,4);

Golang的不定参数

在很多语言中都提供了不定参数和函数重载以及函数式语言中得闭包来提高函数的灵活性.如果使用过fmt包里的函数,那么你就已经接触到了Golang的不定参数了.那么如何定义一个自己的不定参数的函数呢? 一.函数定义 首先来看如何定义一个不定参数的函数: func YourFun(v... interface{}){ } 该函数定义,定义了一个接受任何数目任何类型参数的函数.这里特殊的语法是三个点"...",在一个变量后面加上三个点后,表示从该处开始接受不定参数,不同于python,golan

了解golang的不定参数(... parameters),这一篇就够了

在实际开发中,总有一些函数的参数个数是在编码过程中无法确定的,比如我们最常用的fmt.Printf和fmt.Println: fmt.Printf("一共有%v行%v列\n", rows, cols) fmt.Println("共计大小:", size) 当你需要实现类似的接口时,就需要我们的不定参数出场了. golang的不定参数 顾名思义,不定参数就是一个占位符,你可以将1个或者多个参数赋值给这个占位符,这样不管实际参数的数量是多少,都能交给不定参数来处理,我们

有关 java 不定参数

不定参数实际为数组参数的一种写法而已,本质上与数组参数完全相同 //1.数组参数函数 public static int sum(int[] values) { } //2.不定参数函数 不定参数只能是,形参的最后一个参数 public static int sum(int... values) } // 3. 不定参数直接当做数组来使用 private static int sum(int... values) { int sum = 0; for (int i = 0; i < values

c语言重载(overriding in C)或函数不定参数个数

google一下 c overiding发现有这样一段英文解释: Because C doesn't require that you pass all parameters to the function if you leave the parameter list blank in the prototype. The compiler should only throw up warnings if the prototype has a non-empty parameter list

C和C++中的不定参数

在初学C的时候,我们都会用到printf函数来写Hello World的程序.在我们看printf函数的声明时,会看到类似于下面代码 int printf(const char * __restrict, ...); 另外,在我们学习C和C++的时候,函数的声明总是确定个数和类型的,而我们在用printf的时候,却可以一次输出多个参数. 这就是我们要提的不定参数了. 在32位的C和C++编程中,函数调用是有规约的,并且各个编译器也基本达成了一致,尽管他们编译出的东西基本不能通用.关于调用规约的东

C语言不定参数

最近,遇到一个c语言的不定参数问题.其实,对于c语言的不定参数问题,只需要三个函数就可以搞定了.这三个函数的头文件是<stdarg.h>,其实下面的三个函数都是一个宏定义(macro).    这三个函数是:    void va_start(va_list ap, last);    type va_arg(va_list ap, type);    void va_end(va_list ap);    如果需要进行其他的一些操作,可以查看一下man手册进行查询.    在这三个函数解释之