C 将数组的所有元素传递给具有可变参数的函数(…)

C 将数组的所有元素传递给具有可变参数的函数(…),c,parameters,optional-parameters,C,Parameters,Optional Parameters,我需要将可变数量的参数传递给允许可变数量参数的c函数 function a(int n , ...) {...} //*n* number of parameters int b[XXX]; //XXX is more or less run-time dynamic. //Filsignals.https://github.com/libpd/libpd/blob/master/pure-data/src/d_ugen.cl b with things. a(n, b[0], b[1] ..

我需要将可变数量的参数传递给允许可变数量参数的c函数

function a(int n , ...) {...} //*n* number of parameters

int b[XXX]; //XXX is more or less run-time dynamic.
//Filsignals.https://github.com/libpd/libpd/blob/master/pure-data/src/d_ugen.cl b with things.
a(n, b[0], b[1] ... b[XXX])
如何在不命名b的每个元素的情况下编写此代码

有一件事:我无法更改
a()
的实现,它使用
va_列表
访问“…”。 因此,我不能传递
a(n,b)
,因为“b”只能作为一个参数处理,但它包含更多参数

更多细节:a()实际上是puredata
dsp\u add()
函数(在中定义),它使用传递的指针设置传入和传出

一种选择 我刚刚发现我可以通过使用来避免这个问题,这是variadic
dsp\u add()
函数的数组版本

但是,这并不能回答我的问题……

是可以修改的
还是其他api的一部分

如果您可以更改它,而不是使用可变函数,我将函数定义为:

function a(int n, int* params)
{
    /*...*/
}
然后把数组传给它


如果它不是一个选项,我将研究并将其实现为包装器函数,这样您就可以将数组传递给它,使代码尽可能简单。

您已经找到了问题的答案。我认为使用函数的数组变量是一种可行的方法。(关于
dsp\u addv
功能的评论很有说服力。)

然而,这并不能回答我的问题

根据可变函数的性质,您可以编写一个调用可变函数的包装函数。这并不适用于所有情况,但适用于某些常见情况。(可变函数本身在使用上受到了很大的限制。在某个地方,我读过一篇文章,声称它们的存在只是为了实现
printf

迭代 对每个变量参数都进行了处理:例如,打印变量,或者将变量添加到列表中。在这种情况下,您可以为每个参数调用函数:

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

void varg_print(const char *str, ...)
{
    va_list va;

    va_start(va, str);
    while (str) {
        puts(str);
        str = va_arg(va, const char *);
    }
    va_end(va);
}

void arr_print(const char **str)
{    
    while (*str) varg_print(*str++, NULL);
}

int main()
{
    const char *fruit[]) = {"apple", "pear", "banana", NULL};
    arr_print(fruit);

    return 0;
}
#包括
#包括
void varg_打印(常量字符*str,…)
{
va_列表va;
va_启动(va,str);
while(str){
put(str);
str=va_arg(va,const char*);
}
va_端(va);
}
无效arr_打印(常量字符**str)
{    
while(*str)varg_print(*str++,NULL);
}
int main()
{
const char*fruit[])={“苹果”、“梨”、“香蕉”,NULL};
arr_print(水果);
返回0;
}
减少 所有参数都减少为单个值,例如它们的总和或最大值。在这里,您可以处理子数组,直到得到所需的内容。下面的示例一次最多将数组转发给四个元素的求和函数,并用结果覆盖数组的较低区域,直到只剩下一个值

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

double varg_sum(int n, ...)
{
    double s = 0.0;
    va_list va;

    va_start(va, n);
    while (n--) s += va_arg(va, double);
    va_end(va);

    return s;
}

double arr_sum(int n, double *x)
{
    double r[n];

    if (n <= 0) return 0.0;

    memcpy(r, x, n * sizeof(*x));

    while (n > 1) {
        double *p = r;
        int m = 0;

        while (n) {
            switch (n) {
            case 1:     r[m++] = varg_sum(1, p[0]);
                        n -= 1;
                        p += 1;
                        break;

            case 2:     r[m++] = varg_sum(2, p[0], p[1]);
                        n -= 2;
                        p += 2;
                        break;

            case 3:     r[m++] = varg_sum(3, p[0], p[1], p[2]);
                        n -= 3;
                        p += 3;
                        break;

            default:    r[m++] = varg_sum(4, p[0], p[1], p[2], p[3]);
                        n -= 4;
                        p += 4;
                        break;
            }
        }

        n = m;   
    }

    return r[0];
}

int main()
{
    double x[100];
    int i;

    for (i = 0; i < 100; i++) x[i] = i + 1.0;
    printf("%g\n", arr_sum(100, x));   

    return 0;
}
#包括
#包括
#包括
#包括
双变量和(整数n,…)
{
双s=0.0;
va_列表va;
va_启动(va,n);
而(n--)s+=va_arg(va,double);
va_端(va);
返回s;
}
双arr_和(整数n,双*x)
{
双r[n];
if(n1){
双*p=r;
int m=0;
while(n){
开关(n){
案例1:r[m++]=varg_和(1,p[0]);
n-=1;
p+=1;
打破
案例2:r[m++]=varg_和(2,p[0],p[1]);
n-=2;
p+=2;
打破
案例3:r[m++]=varg_和(3,p[0],p[1],p[2]);
n-=3;
p+=3;
打破
默认值:r[m++]=varg_和(4,p[0],p[1],p[2],p[3]);
n-=4;
p+=4;
打破
}
}
n=m;
}
返回r[0];
}
int main()
{
双x[100];
int i;
对于(i=0;i<100;i++)x[i]=i+1.0;
printf(“%g\n”,arr_sum(100,x));
返回0;
}

这段代码复制了一个数组,这样原始数组就不会被破坏。为了更有效地处理较大的数组,您可以增加数据块大小,但是可变函数并不是为长可变列表设计的,所以四个似乎是可以的。

将数组作为参数void func(a)传递;它的可能副本可能有助于了解
a
的功能。例如,如果它只是单独处理所有参数,您可以编写一个包装器循环。如果它是一个从输入中计算单个值的归约函数,那么可能没有好的方法来做您想要做的事情。恐怕您做不到,除非您使用一些难看的宏魔术。@2501我不喜欢魔术;)我会选择dsp_addv(),这样就可以了。