2013-01-04 145 views
1

可能重複:
C++ preprocessor __VA_ARGS__ number of arguments
How to count the number of arguments passed to a function that accepts a variable number of arguments?可變參數功能

要了解可變參數的功能,我寫了一個演示:

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

int foo(int n, int m, ...); 

int 
main (int argc, char *argv[]) 
{ 
    int n = 10; 
    int m = 15; 
    int p = 20; 
    // foo (n, m); 
    foo (n, m, 20); 

    return EXIT_SUCCESS; 
} 

int foo (int n, int m, ...) 
{ 
    va_list ap; 
    int p; 
    char *str; 

    va_start (ap, m); 
    p = va_arg (ap, int); 
    n = m + p; 
    printf ("%d.\n", n); 
    va_end (ap); 
    return 0; 
} 

我想知道如何處理fu如果它只有2個參數。 (在該演示中,如果僅僅nm,運行foo後,我希望得到的結果:n = n+m

+1

@RedX:該重複是可變宏,而不是可變參數函數。 – netcoder

回答

0

不知道我理解的問題,但如果你只有一個參數在varlist中的功能例如foo(int n,...),然後是...然後你可以在va_start()中傳遞foo的第一個參數(在我們的例子中是n),它將一直工作。

int foo (int n, ...); 
int 
main (int argc, char *argv[]) 
{ 
    int n = 10; 
    int m = 15; 
    int p = 20; 

    foo (n, m); 
    // foo (n, m, 20); 

    return EXIT_SUCCESS; 
} 

int foo (int n, ...) 
{ 
    va_list ap; 
    int p; 
    char *str; 

    va_start (ap, n); 
    p = va_arg (ap, int); 
    n = n + p; 
    printf ("%d.\n", n); 
    va_end (ap); 
    return 0; 
} 
1

對於每一個變量參數(「可變參數」)功能,必須有對知道有多少爭論它必須處理功能的方式。有多種處理方式。

  • 功能的printf()scanf()家庭使用格式字符串以確定有多少參數傳遞給函數。
  • POSIX open()函數查看第二個參數中的選項以確定是否存在第三個參數。
  • POSIX execl()函數掃描,直到遇到空指針參數。
  • 您可以傳遞要處理的參數數量的明確計數(請參見example,編號Fei Jiang)。

所有這些方法的工作。 open()機制是最不常見也是最奇特的(主要產生於歷史怪癖)。

但是必須使用一種這樣的機制。被調用的函數必須能夠告訴(以某種方式)它何時完成了對其參數列表的變量部分的處理。

除非您將可變長度參數列表中繼給其他函數(例如,您使用vsnprintf()來格式化傳遞給函數的變量參數的字符串),否則您的可變參數函數體將需要一個循環來處理變量數的論據。你的功能缺少該循環。

1

在運行時,無法知道va_list中實際的附加參數數量。因此,應該有另一種方法來推斷這個數字,例如從以前的參數或從一些列表結束約定(如在,給出任何數量的指針後跟NULL)。考慮printf,其中格式字符串決定va_list部分中期望的參數(具體類型)。

只要您考慮到這一點,參數的最小數量(即空的va_list)就沒有什麼特別之處。當你知道沒有什麼可期望的時候,不要從va_list中彈出任何東西。

1

我不明白你想要什麼「富」做的,但通常FOO應該有它的一個循環,也FOO應該被告知多少個參數時調用,或者更確切地說,它已被賦予,當循環結束時。通過printf的知道這%d%S%F ...第一炭*模式參數

例如,如果我們想編寫一個返回幾個整數和功能,我們可以實現這樣

#include <stdio.h> 
#include <stdarg.h> 
int int_sum(int count, ...) { 
    int sum = 0, i; 
    va_list ap; 
    va_start(ap, count); 
    for (i = 0; i < count; ++i) { 
     sum += va_arg(ap, int); 
    } 
    va_end(ap); 
    return sum; 
} 

int main() { 
    printf("%d\n", int_sum(5, 1, 2, 3, 4, 5)); 
    return 0; 
} 
+0

+1:關於循環的好處是必要的!並且要處理的參數個數是確定向函數傳遞多少個參數的可能技術之一。 –

+0

我想編寫一個像這樣的節點插入函數: node_insert(list,new), node_insert(list,new_elem,pos) 如果它帶有2個參數,它將從頭中插入節點,如果它帶有3個參數,它會將節點插入節點elem == pos的位置。 –

+0

@VincentZhang在這種情況下使用可變參數函數是不合適的。 –