跳转到内容

可變參數函數

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

計算機程序設計,一個可變參數函數是指一個函數擁有不定引數,即是它接受一個可變數目的參數。不同的程式語言對可變參數函數的支持有很大差異。

一般而言,在設計函數時會遇到許多數學邏輯操作,是需要一些可變功能。例如,計算數字串的總和、字符串的聯接或其他操作過程,都可以存在任意數量的參數。

另一種許多語言都實現為可變參數函數的是格式輸出函數,在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