
_START_ARTICLE_
可變參數函數
_START_PARAGRAPH_
在计算机程序设计，一个可变参数函数是指一个函数拥有不定引数，即是它接受一个可变数目的参数。不同的编程语言对可变参数函数的支持有很大差异。_NEWLINE_一般而言，在设计函数时会遇到许多数学和逻辑操作，是需要一些可变功能。例如，计算数字串的总和、字符串的联接或其他操作过程，都可以存在任意数量的参数。_NEWLINE_另一种许多语言都实现为可变参数函数的是格式输出函数，在C语言的printf函数和Common Lisp的format函数就是例子。这些函数都需要一个参数，指定格式的输出，再读取可变参数的值进行格式化。_NEWLINE_另外，可变参数函数在某些语言存在安全问题。例如C语言在没有长度检查和类型检查，在传入过少的参数或不符的类型时可能会出现溢位的情况，更可能会被利用为攻击目标。所以，在设计函数时可以先考虑其他替补方案，例如以类型安全的方式——重载。
_START_SECTION_
C/C++
_START_PARAGRAPH_
在C语言中，C标准函式库的stdarg.h标头档定义了提供可变参数函数使用的宏。在C++，应该使用标头档cstdarg。_NEWLINE_要创建一个可变参数函数，必须把省略号（...）放到参数列表后面。函数内部必须定义一个va_list变数。然后使用宏va_start、va_arg和va_end来读取。例如：_NEWLINE_#include <stdio.h>#include <stdarg.h>double average(int count, ...); /* 函数声明，计算参数的平均值。直到参数为0时停止计算*/int main(void) /* 测试代码*/{_NEWLINE_        double avg;_NEWLINE_        avg = average(3, 2, 1, 5, 0);_NEWLINE_        printf("%f\n", avg);_NEWLINE__NEWLINE_        return 0;}double average(int count, ...){_NEWLINE_        va_list ap;_NEWLINE__NEWLINE_        int i, cnt = 0;  /* cnt 表示参数个数*/_NEWLINE_        double tot = 0;  /* 参数的和*/_NEWLINE_        va_start(ap, count);_NEWLINE_        for (i = count; i; i = va_arg(ap, int), cnt++) /* i为当前获取参数的值*/_NEWLINE_                tot += i;_NEWLINE_        va_end(ap);  /* 将参数列表清空*/_NEWLINE_        return tot / cnt;}_NEWLINE_这个是一段计算平均数的程式码，可以输入任意数量的小数并计算平均数，注意计算以0停止计算。请注意，函数不知道参数的数量或它们的类型，这里要求的类型是double，而且第一个参数传递可变参数的数量。在另外的情况​​下，例如printf，参数的数量和类型都设定在格式字符串中。在这两种情况下，程序员实际上需要提供正确的参数，如果参数传递少了或参数的类型不正确，导致读入内存的无效区（溢位），这样会有安全漏洞如格式字符串攻击。
_START_SECTION_
C++11/C++14
_START_PARAGRAPH_
C++11新增了initializer_list物件，当编译器遇到大括号阵列变成函数的参数时，会自动将大括号阵列转型成initializer_list物件，因此可以使用此原理来做出“相同型别”参数的可变参数函数。_NEWLINE_#include <iostream>using namespace std;template<typename T>T sum(initializer_list<T> il) {_NEWLINE_T data(0);_NEWLINE_for (T i : il)_NEWLINE_data += i;_NEWLINE_return data;}int main() {_NEWLINE_cout << sum( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }) << endl;_NEWLINE_return 0;}
_START_SECTION_
JavaScript
_START_PARAGRAPH_
在JavaScript(简称js)中，函数的可变参数用法很巧妙。_NEWLINE_function test(){_NEWLINE_ // 不管函数是否声明参数，所有的参数都会添加到arguments中，arguments以数组的形式将参数保存起来_NEWLINE_ var params = arguments;_NEWLINE_ // 以数组的形式输出_NEWLINE_ console.log(params);};test("a");// 结果：["a"]test("a", 1);// 结果：["a", 1]test("a", 1, function(){});// 结果：["a", 1, function (){}]