将数组的所有元素传递给具有可变参数的函数(...) [英] Passing all elements of an array to a function with variable parameters (...)

查看:390
本文介绍了将数组的所有元素传递给具有可变参数的函数(...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to pass a variable number of parameters to a c-function that allows a variable number of parameters.

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的每个元素的情况下编写此代码?

How to write this without naming each single element of b?

一件事:我无法更改a()的实现,它使用va_list来访问"...". 因此,我不能传递a(n, b),因为"b"仅作为 one 参数处理,但包含更多参数.

One thing: I cannot change the implementation of a() and it uses the va_list to access "...". Thus, I cannot pass a(n, b) as "b" would only be handled as one parameter only, but it contains more.

更多细节:a()实际上是puredata dsp_add()函数(在

Just more details: a() is actually the puredata dsp_add() function (defined in d_ugen.c) that is uses the passed pointers to set up incoming and outgoing.

我刚刚发现我可以通过使用 dsp_addv() ,它是可变参数dsp_add()函数的数组版本.

I just found that I can avoid this problem by using dsp_addv(), which is an array version of the variadic dsp_add() function.

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

However, this does not answer my question...

推荐答案

您已经找到问题的答案.我认为使用函数的数组变体是要走的路. (对dsp_addv函数的注释正在说明.)

You have already found an answer to your problem. I think using the array variant of the function is the way to go. (The comment on the dsp_addv function is telling.)

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

However, this does not answer my question...

根据可变参数函数的性质,可以编写一个调用可变参数函数的包装器函数.这并非在所有情况下都适用,但在某些情况下适用. (可变参数函数本身在使用上受到很大限制.在某些地方,我读过一个声称它们仅用于实现printf的说法.)

Depending on the nature of the variadic function, you can write a wrapper function that calls the variadic function. This will not work in all cases, but for some frequent cases. (Variadic functions themselves are rather restricted in their use. Somewhere, I've read a claim that they exist only to implement printf.)

对每个可变参数执行某些操作:例如,将其打印出来,或将其添加到列表中.在这种情况下,您只需为每个参数调用函数即可:

Something is done to each variadic argument: It is printed, for example, or it is added to a list. In that case you can just call the function for each argument:

#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;
}

减少

所有参数均减小为单个值,例如,它们的总和或最大值.在这里,您可以处理子数组,直到获得所需的内容为止.下面的示例一次将数组最多转发到四个元素的求和函数,并用结果覆盖数组的下部区域,直到只剩下一个值为止.

Reduction

All arguments are reduced to a single value, for example their sum or their max values. Here you can treat sub-arrays until you get what you want. The example below forwards an array to a summation function at most four elements at a time and overwrites the lower regions of the array with the result until there is only a single value left.

#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;
}

代码会复制数组,以免破坏原始数组.您可以增加块的大小,以便更有效地处理更大的数组,但是可变参数函数并不是为较长的可变参数列表设计的,所以四个似乎还可以.

The code makes a copy of the array so that the original array isn't destroyed. You can increase the chunk size in order to treat bigger arrays more effectively, but variadic functions aren't designed for long variadic lists anyway, so four seems okay.

这篇关于将数组的所有元素传递给具有可变参数的函数(...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆