可能重复:
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;
}
如果只有2个参数,我想知道如何处理该函数。
(对于此演示,如果只有n
和m
,则在运行foo
后,我想获得结果:n = n+m
)
答案 0 :(得分:1)
对于每个变量参数('variadic')函数,必须有一种方法让函数知道它必须处理多少个参数。有各种方法可以处理。
printf()
和scanf()
系列函数使用格式字符串来确定传递给函数的参数数量。open()
函数查看第二个参数中的选项,以了解是否存在第三个参数。execl()
函数会一直扫描,直到遇到空指针参数。所有这些方法都有效。 open()
机制是最不通用和最特殊的(主要来自历史怪癖)。
但必须使用一种这样的机制。被调用的函数必须能够(以某种方式)告诉它何时完成了对其参数列表的变量部分的处理。
除非您将可变长度参数列表转发给其他函数(例如,使用vsnprintf()
格式化传递给函数的变量参数的字符串),您的可变参数函数体将需要一个循环来处理可变数量的参数。你的功能缺少那个循环。
答案 1 :(得分:1)
在运行时,无法从va_list中了解其他参数的实际数量。因此,应该有另一种方法来推断这个数字,例如来自先前的参数或来自某些列表末尾的约定(如同,给出任意数量的指针后跟NULL)。考虑printf
,其中格式字符串确定va_list部分中预期的参数(具体类型)。
只要考虑到这一点,最小参数数量就没有什么特别之处(即空的va_list)。当你知道没有什么可以期待的时候,不要从va_list弹出任何东西。
答案 2 :(得分:1)
我不明白你想要'foo'做什么,但通常foo应该有一个循环,而foo应该被告知多少参数它在调用时给出,或者更确切地说,当循环结束时给出。 printf在第一个char * pattern参数
中通过%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;
}
答案 3 :(得分: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;
}