在声明/编译时带参数的 C 函数指针
C Function pointers with parameter at declaration/ compile time
假设我们有一个事件列表(int)和动作(函数指针),如:
typedef struct action_type {
int event;
int (*func)();
} action_type;
action_type actions[] = {
{ my_event1, my_action1 },
{ my_event2, my_action2 },
{ my_event3, my_action3 },
{ my_event4, my_action1 }
}
我想为 运行 作为 table 的一部分的操作添加条件,因为
- 更好的可读性和
- 动作函数的简化。
action_type actions[] = {
{ my_event1, exceeds(&temperature, 100) , my_action1 },
{ my_event1, between(&temperature, 50, 80), my_action2 },
...
}
有没有办法得到这样的符号?
或者我需要创建类似的东西:
action_type actions[] = {
{ my_event1, $temperature, exceeds, 100, my_action1 },
...
}
但是,这种方法只允许固定数量和固定类型的参数。由于我正在编写一个库,条件几乎可以是任何东西,所以我正在寻找一种方法来允许 condition() 函数使用不同的变量类型和不同的参数计数。
编辑:添加了关于可能具有不同数量和类型参数的条件的附加信息。
我会使用 X_MACRO,即:像这样的东西:
#define MY_EVENT_1 1
#define MY_EVENT_2 2
#define MY_EVENT_3 3
static int my_action1(void) { printf("Over 100!\n"); return 0; }
static int my_action2(void) { printf("Over 120!\n"); return 0; }
static int my_action3(void) { printf("Over 160!\n"); return 0; }
static int exceeds(int *val, int temp) { return *val > temp; }
typedef struct action_type {
int event;
int (*func)();
} action_type;
#define X_ACTIONS \
X(MY_EVENT_1, exceeds(&temperature, 100), my_action1) \
X(MY_EVENT_2, exceeds(&temperature, 120), my_action2) \
X(MY_EVENT_3, exceeds(&temperature, 160), my_action3)
static action_type actions[] = {
#define X(type, cond, cb) { type, cb },
X_ACTIONS
#undef X
};
int main() {
int temperature = 130;
#define X(type, cond, cb) if (cond) cb();
X_ACTIONS
#undef X
return 0;
}
你可以这样做
#define __NO__FUNC NULL
typedef unsigned char (*func)(void);
typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3);
typedef struct {
int event
func custom_func;
con condition;
} action_type;
然后像这样使用
action_type action[] = {
{ 1,SomeFunc, SomeCondition },
{ 2,__NO__FUNC,__NO__FUNC },
};
其中某些函数必须返回 unsigned char 并且输入类型为 void,例如
unsigned char SomeFunc(void)
{
// some logic
return 1;
}
unsigned char SomeCondition(unsigned char param1, unsigned char param2, unsigned char param3)
{
// logic
return 1;
}
并像这样使用它
if (action[0].condition(1,2,3)){
action[0].custom_func();
}
您还可以通过以下示例检查是否设置了功能:
if (action[0].condition(1,2,3)){
if(action[0].custom_func)
action[0].custom_func();
}
一起使用示例
unsigned char SomeFunc(void)
{
// some logic
return 1;
}
unsigned char SomeCondition(unsigned char param1, unsigned char param2, unsigned char param3)
{
// logic
return 1;
}
#define __NO__FUNC NULL
typedef unsigned char (*func)(void);
typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3);
typedef struct {
int event
func custom_func;
con condition;
} action_type;
action_type action[] = {
{ 1,SomeFunc, SomeCondition },
{ 2,__NO__FUNC,__NO__FUNC },
};
void main(void)
{
unsigned char temperature = 0;
unsigned char val = 30;
unsigned char another_val = 50;
if (action[0].condition(temperature ,val,another_val )){
action[0].custom_func();
}
}
更新:我添加了第二个函数参数,称为条件,可用于在执行 custom_func()
之前检查输出
更新 2:添加了接受变量作为输入的条件函数
更新 3:我已经添加了一个如何使用它的示例代码,但是我想指出的是,在您的问题中,这些函数的声明中不能有可变数量的参数。 C 语法不允许这样做。
在“typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3)”类型的结构中创建了一个元素;
“
意味着这些元素接受 returns unsigned char 的函数并且输入为 (unsigned char param1, unsigned char param2, unsigned char param3);
您不能添加具有不同 return 类型或不同参数的函数。
希望对您有所帮助!
最好的问候
假设我们有一个事件列表(int)和动作(函数指针),如:
typedef struct action_type {
int event;
int (*func)();
} action_type;
action_type actions[] = {
{ my_event1, my_action1 },
{ my_event2, my_action2 },
{ my_event3, my_action3 },
{ my_event4, my_action1 }
}
我想为 运行 作为 table 的一部分的操作添加条件,因为
- 更好的可读性和
- 动作函数的简化。
action_type actions[] = {
{ my_event1, exceeds(&temperature, 100) , my_action1 },
{ my_event1, between(&temperature, 50, 80), my_action2 },
...
}
有没有办法得到这样的符号?
或者我需要创建类似的东西:
action_type actions[] = {
{ my_event1, $temperature, exceeds, 100, my_action1 },
...
}
但是,这种方法只允许固定数量和固定类型的参数。由于我正在编写一个库,条件几乎可以是任何东西,所以我正在寻找一种方法来允许 condition() 函数使用不同的变量类型和不同的参数计数。
编辑:添加了关于可能具有不同数量和类型参数的条件的附加信息。
我会使用 X_MACRO,即:像这样的东西:
#define MY_EVENT_1 1
#define MY_EVENT_2 2
#define MY_EVENT_3 3
static int my_action1(void) { printf("Over 100!\n"); return 0; }
static int my_action2(void) { printf("Over 120!\n"); return 0; }
static int my_action3(void) { printf("Over 160!\n"); return 0; }
static int exceeds(int *val, int temp) { return *val > temp; }
typedef struct action_type {
int event;
int (*func)();
} action_type;
#define X_ACTIONS \
X(MY_EVENT_1, exceeds(&temperature, 100), my_action1) \
X(MY_EVENT_2, exceeds(&temperature, 120), my_action2) \
X(MY_EVENT_3, exceeds(&temperature, 160), my_action3)
static action_type actions[] = {
#define X(type, cond, cb) { type, cb },
X_ACTIONS
#undef X
};
int main() {
int temperature = 130;
#define X(type, cond, cb) if (cond) cb();
X_ACTIONS
#undef X
return 0;
}
你可以这样做
#define __NO__FUNC NULL
typedef unsigned char (*func)(void);
typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3);
typedef struct {
int event
func custom_func;
con condition;
} action_type;
然后像这样使用
action_type action[] = {
{ 1,SomeFunc, SomeCondition },
{ 2,__NO__FUNC,__NO__FUNC },
};
其中某些函数必须返回 unsigned char 并且输入类型为 void,例如
unsigned char SomeFunc(void)
{
// some logic
return 1;
}
unsigned char SomeCondition(unsigned char param1, unsigned char param2, unsigned char param3)
{
// logic
return 1;
}
并像这样使用它
if (action[0].condition(1,2,3)){
action[0].custom_func();
}
您还可以通过以下示例检查是否设置了功能:
if (action[0].condition(1,2,3)){
if(action[0].custom_func)
action[0].custom_func();
}
一起使用示例
unsigned char SomeFunc(void)
{
// some logic
return 1;
}
unsigned char SomeCondition(unsigned char param1, unsigned char param2, unsigned char param3)
{
// logic
return 1;
}
#define __NO__FUNC NULL
typedef unsigned char (*func)(void);
typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3);
typedef struct {
int event
func custom_func;
con condition;
} action_type;
action_type action[] = {
{ 1,SomeFunc, SomeCondition },
{ 2,__NO__FUNC,__NO__FUNC },
};
void main(void)
{
unsigned char temperature = 0;
unsigned char val = 30;
unsigned char another_val = 50;
if (action[0].condition(temperature ,val,another_val )){
action[0].custom_func();
}
}
更新:我添加了第二个函数参数,称为条件,可用于在执行 custom_func()
之前检查输出更新 2:添加了接受变量作为输入的条件函数
更新 3:我已经添加了一个如何使用它的示例代码,但是我想指出的是,在您的问题中,这些函数的声明中不能有可变数量的参数。 C 语法不允许这样做。
在“typedef unsigned char (*con)(unsigned char param1, unsigned char param2, unsigned char param3)”类型的结构中创建了一个元素; “
意味着这些元素接受 returns unsigned char 的函数并且输入为 (unsigned char param1, unsigned char param2, unsigned char param3);
您不能添加具有不同 return 类型或不同参数的函数。
希望对您有所帮助! 最好的问候