跳转到内容

可变参数函数

本页使用了标题或全文手工转换
维基百科,自由的百科全书

电脑程式设计,一个可变参数函数是指一个函数拥有不定引数,即是它接受一个可变量目的参数。不同的编程语言对可变参数函数的支持有很大差异。

一般而言,在设计函数时会遇到许多数学逻辑操作,是需要一些可变功能。例如,计算数字符串的总和、字符串的联接或其他操作过程,都可以存在任意数量的参数。

另一种许多语言都实现为可变参数函数的是格式输出函数,在C语言printf函数和Common Lispformat函数就是例子。这些函数都需要一个参数,指定格式的输出,再读取可变参数的值进行格式化。

另外,可变参数函数在某些语言存在安全问题。例如C语言在没有长度检查和类型检查,在传入过少的参数或不符的类型时可能会出现溢出的情况,更可能会被利用为攻击目标。所以,在设计函数时可以先考虑其他替补方案,例如以类型安全的方式——重载

例子

[编辑]

C/C++

[编辑]

C语言中,C标准函数库stdarg.h头文件定义了提供可变参数函数使用的。在C++,应该使用头文件cstdarg

要创建一个可变参数函数,必须把省略号(...)放到参数表表后面。函数内部必须定义一个va_list变量。然后使用va_startva_argva_end来读取。例如:

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

double average(int count, ...); /* 函数声明,计算参数的平均值。直到参数为0时停止计算 */

int main(void) /* 测试代码 */
{
        double avg;
        avg = average(3, 2, 1, 5, 0);
        printf("%f\n", avg);

        return 0;
}

double average(int count, ...)
{
        va_list ap;

        int i, cnt = 0;  /* cnt 表示参数个数 */
        double tot = 0;  /* 参数的和 */
        va_start(ap, count);
        for (i = count; i; i = va_arg(ap, int), cnt++) /* i为当前获取参数的值 */
                tot += i;
        va_end(ap);  /* 将参数列表清空 */
        return tot / cnt;
}

这个是一段计算平均数的代码,可以输入任意数量的小数并计算平均数,注意计算以0停止计算。请注意,函数不知道参数的数量或它们的类型,这里要求的类型是double,而且第一个参数传递可变参数的数量。在另外的情况​​下,例如printf,参数的数量和类型都设置在格式字符串中。在这两种情况下,程序员实际上需要提供正确的参数,如果参数传递少了或参数的类型不正确,导致读入内存的无效区(溢出),这样会有安全漏洞如格式字符串攻击。

C++允许函数重载。对于重载函数,有省略符的可变参数函数的匹配优先级最低。只有其它重载函数都不能匹配时,才会与候选的可变参数函数匹配。

C++11/C++14

[编辑]

C++11新增了initializer_list物件,当编译器遇到大括号数组变成函数的参数时,会自动将大括号数组转型成initializer_list物件,因此可以使用此原理来做出“相同类型”参数的可变参数函数。

#include <iostream>
using namespace std;
template<typename T>
T sum(initializer_list<T> il) {
	T data(0);
	for (T i : il)
		data += i;
	return data;
}
int main() {
	cout << sum( { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }) << endl;
	return 0;
}

JavaScript

[编辑]

在JavaScript(简称js)中,函数的可变参数用法很巧妙。

function test(){
 // 不管函数是否声明参数,所有的参数都会添加到arguments中,arguments以数组的形式将参数保存起来
 var params = arguments;
 // 以数组的形式输出
 console.log(params);
};
test("a");// 结果:["a"]
test("a", 1);// 结果:["a", 1]
test("a", 1, function(){});// 结果:["a", 1, function (){}]

参见

[编辑]

外部链接

[编辑]
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy