我正在嘗試創建一個函式,它將使用 C 中提供的子引數執行一個函式。比如:
int function(void (*func)(), ...) // add as many arguments you want for 'func()'
{
va_list ptr;
...
func(sub_arguments) // the '...'
}
void *abc(int a) { ... }
void *one(int b, int c) { ... }
int main()
{
function(abc, 73);
function(one, 9, 84);
}
現在,有沒有辦法以某種方式制作一個變數串列并將其添加為引數并執行它?如果是這樣,怎么做?
我知道我以非常困難的方式表達了這個問題,但我就是不知道如何做到這一點。
uj5u.com熱心網友回復:
您可以提取每個引數function()并進行相關呼叫:
#include <stdio.h>
#include <stdarg.h>
void abc(int a) {
printf("abc(%d)\n", a);
}
void one(int b, int c) {
printf("one(%d,%d)\n", b, c);
}
int function(void (*func)(), ...) {
va_list ap;
va_start(ap, func);
if(func == abc) {
int a = va_arg(ap, int);
func(a);
} else if(func == one) {
int b = va_arg(ap, int);
int c = va_arg(ap, int);
func(b, c);
}
va_end(ap);
return 0;
}
int main() {
function(abc, 73);
function(one, 9, 84);
}
或者將您的子函式更改為采用 va_list,然后將其從函式傳遞給子函式。這可能是我會采取的方法。如果想直接呼叫您的子函式,為每個接受 ... 引數(likeprintf()和vpritnf()pair)的子函式撰寫一個包裝器。請注意,這要求子函式具有固定引數,例如function()has func。
uj5u.com熱心網友回復:
一種選擇可能是根本不使用可變引數函式,而是使用 C11_Generic選擇來呼叫function與它應該中繼到的引數完全匹配的實作func。
使用此解決方案,如果您在提供引數時出錯,您將獲得編譯時檢查您是否提供了兼容的引數,而不是在運行時獲得未定義的行為。
#include <stdio.h>
int function_impl_1(void(*func)(int), int a) {
func(a);
return 0;
}
int function_impl_2(void(*func)(int, int), int a, int b) {
func(a, b);
return 0;
}
#define function(X, ...) _Generic((X), \
void(*)(int): function_impl_1, \
void(*)(int, int): function_impl_2 \
)(X, __VA_ARGS__)
void abc(int a) {
printf("abc(%d)\n", a);
}
void one(int b, int c) {
printf("one(%d,%d)\n", b, c);
}
void two(int b, int c) {
printf("two(%d,%d)\n", b, c);
}
int main(void) {
function(abc, 73);
function(one, 9, 84);
function(two, 123, 456);
}
演示
具有零可變引數的可變引數宏是有問題的。有一個 GNU 擴展__VA_OPT__(來自 C 20),可用于:
#define function(X, ...) _Generic((X), \
void(*)(void): function_impl_0, \
void(*)(int): function_impl_1, \
void(*)(int, int): function_impl_2 \
)((X) __VA_OPT__(,) __VA_ARGS__)
void zero(void) {
puts("zero()");
}
// ...
function(zero);
演示
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/512651.html
標籤:C功能论据
