每当我们使用C语言中的可变参数函数时,都必须提供参数总数作为第一个参数。有没有什么方法可以使函数具有可变的参数而不给出参数的总数?
[从comment更新:]
我想使用诸如sum(1,2,3)之类的函数应返回6,即那里不存在任何计数器。
答案 0 :(得分:7)
几种方法:
无论如何,您必须有某种方法让函数知道varargs的类型,以及知道它们何时结束的方法。 C中没有内置方法,参数计数不会传递给函数。
答案 1 :(得分:5)
我想使用诸如sum(1,2,3)之类的函数应返回6,即没有计数器存在
您可以定义一个哨兵。在这种情况下,@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request.
}
}
可能有意义。
0
这样称呼它:
/* Sums up as many int as required.
Stops adding when seeing the 1st 0. */
int sum(int i, ...)
{
int s = i;
if (s)
{
va_list ap;
va_start(ap, i);
/* Pull the next int from the parameter list and if it is
equal 0 leave the while-loop: */
while ((i = va_arg(ap, int)))
{
s += i;
}
va_end(ap);
}
return s;
}
另外,int sum(int i, ...);
int main(void)
{
int s = sum(0); /* Gives 0. */
s = sum(1, 2, 3, 0); /* Gives 6. */
s = sum(-2, -1, 1, 2, 0); /* Gives 0. */
s = sum(1, 2, 3, 0, 4, 5, 6); /* Gives 6. */
s = sum(42); /* Gives undefined behaviour! */
}
函数也可能看起来像这样(但会做一个无用加0的操作):
sum()
答案 2 :(得分:3)
您不必提供那么多参数。例如,考虑printf
的签名:
int printf( const char* format, ... );
它通过解析您给它的字符串来“发现”它需要多少个参数。当然,您的函数需要以 some 的方式知道参数的数量,否则采用可变数量的参数对它有什么意义?
答案 3 :(得分:0)
可以创建一个以计数为第一个参数的可变参数函数,然后使用可变参数宏自动添加计数值:
#include <stdarg.h>
#define count_inner(a1, a2, a3, a4, a5, num, ...) (num)
#define count(...) count_inner(__VA_ARGS__, 5, 4, 3, 2, 1)
#define sum(...) sum_func(count(__VA_ARGS__), __VA_ARGS__)
int sum_func(int count, ...)
{
va_list ap;
va_start(ap, count);
int total = 0;
while(count--)
total += va_arg(ap, int);
va_end(ap);
return total;
}
使用sum
宏而不是sum_func
可以省略计数,只要参数在1到5之间即可。可以根据需要将更多参数/数字添加到count_inner
/ count
宏中。
int main(void)
{
printf("%d\n", sum(1));
printf("%d\n", sum(1, 2));
printf("%d\n", sum(1, 2, 3));
printf("%d\n", sum(1, 2, 3, 4));
}
输出:
1
3
6
10
答案 4 :(得分:0)
好吧,问题在于您必须在某种程度上向函数表明参数列表已用尽。您从printf(3)
中获得了一个方法,即您可以在第一个参数(强制为字符串arg)中表示顺序和参数的类型,也可以在第一个参数中表示它。加,因为值0
实际上并没有加到总和上,因此您可以使用该值(或其他根据您的标准)来表示最后一个参数。例如:
int sum(int a0, ...)
{
int retval = a0;
va_list p;
va_start(p, a0);
int nxt;
while ((nxt = va_arg(p, int)) != 0) {
retval += nxt;
}
return retval;
}
这样,您不必将参数数量作为第一个参数,您只需:
total = sum(1,2,3,4,5,6,7,8,9,10,0);
但是在这种情况下,您必须要小心,不要让中间参数等于零。或者,您也可以使用引用,您可以在引用不是NULL
时添加,例如:
int sum(int *a0, ...)
{
int retval = *a0;
va_list p;
va_start(p, a0);
int *nxt;
while ((nxt = va_arg(p, int*)) != NULL) {
retval += *nxt;
}
return retval;
}
您可以:
int a, b, c, d, e, f;
...
int total = sum(&a, &b, &c, &d, &e, &f, NULL);