通过指针将可变参数函数传递给可变参数函数

问题描述 投票:0回答:2

我对

<stdarg.h>
功能的使用有点困惑。我不知道如何正确地将
va_list
传递给参数函数。这是我想要实现的目标的简化示例:

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

void caller(int (*func)(size_t, ...), size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    va_list args_for_func;
    va_copy(args_for_func, args);
    printf("(");
    for (size_t i = 0; i < n_args-1; i++) {
        printf("%i, ", va_arg(args, int));
    }
    printf("%i) => ", va_arg(args, int));
    int result = func(n_args, args_for_func);
    va_end(args_for_func);
    printf("%i", result);
    va_end(args);
}

int sum(size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    int result = 0;
    for (size_t i = 0; i < n_args; i++) {
        result += va_arg(args, int);
    }
    va_end(args);
    return result;
}

int main() {
    // expected: (1, 2, 3, 4, 5) => 15
    // got: (1, 2, 3, 4, 5) => gibberish
    caller(sum, 5llu, 1, 2, 3, 4, 5);
}
c function function-pointers variadic-functions higher-order-functions
2个回答
0
投票

您不能链接可变参数函数。

sum
的原型应该是:

int sum(size_t n_args, va_list args)

并且

sum
不应该有
va_start
,因为
va_copy
已经做了必要的程序。


0
投票

将可变参数集传递给另一个函数的唯一方法是通过

va_list
,因此您需要更改函数指针以指向使用
va_list
的函数:

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

void caller(int (*func)(size_t, va_list), size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    va_list args_for_func;
    va_copy(args_for_func, args);
    printf("(");
    for (size_t i = 0; i < n_args-1; i++) {
        printf("%i, ", va_arg(args, int));
    }
    printf("%i) => ", va_arg(args, int));
    int result = func(n_args, args_for_func);
    va_end(args_for_func);
    printf("%i", result);
    va_end(args);
}

int vsum(size_t n_args, va_list args) {
    int result = 0;
    for (size_t i = 0; i < n_args; i++) {
        result += va_arg(args, int);
    }
    return result;
}

int sum(size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    int result = vsum(n_args, args);
    va_end(args);
    return result;
}

int main() {
    // expected: (1, 2, 3, 4, 5) => 15
    // got: (1, 2, 3, 4, 5) => gibberish
    caller(vsum, 5llu, 1, 2, 3, 4, 5);
}
© www.soinside.com 2019 - 2024. All rights reserved.