简体   繁体   English

向函数指针添加参数

[英]Add a parameter to a function pointer

I'm using a function pointer to delegate states in C.我正在使用函数指针来委托 C 中的状态。

// states
void state1(int first, int second) {
    ...
}

void state2(int first, int second) {
    ...
}

// state pointer
void (*current_state)(int, int);

// state logic
if (condition1) {
    current_state = &state_1;
} else if (condition2) {
    current_state = &state_2;
}

// do the thing
(*current_state)(1, 2);

Now I'm at a point where the given arguments no longer suffice, so there is a third argument needed.现在我处于给定参数不再足够的地步,因此需要第三个参数。 Since I don't want to change all states, I wondered if it is possible to pass a quasi constant parameter along with the pointer.由于我不想更改所有状态,我想知道是否可以将准常量参数与指针一起传递。 Something like this:像这样的东西:

void state3(int first, int second, int third) {
    ...
}

// state logic
...
else if (condition3) {
    // calculate the constant third argument
    int param3 = 0;

    current_state = &state_3(int, int, param3);
}

I there a way to get this to work?我有办法让它发挥作用吗?

Well I'm not sure I'd recommend it but you could do this sort of thing: 好吧,我不确定我会推荐它,但是您可以执行以下操作:

#include    <stdlib.h>
#include    <stdio.h>
typedef int pfun();
int alice( int a, int b)        { return b; }
int bob( int a, int b, int c)   { return c;     }

int main( )
{
pfun*   f;
    f = alice;
    printf( "%d\n", f( 1, 2, 3));
    f = bob;
    printf( "%d\n", f( 1, 2, 3));

    return EXIT_SUCCESS;
}

This compiles with 这与

gcc -o funp -Wall  funp.c

without warnings and runs correctly. 没有警告,并且运行正常。

The point is that a function declaration like 关键是像

int f();

Says that f is a function that returns an int, with unspecified arguments. 说f是一个返回int的函数,带有未指定的参数。 The downside is that the compiler cannot check that the arguments are of the correct type. 不利之处在于,编译器无法检查参数是否为正确的类型。

You could pass a *void pointer and cast it to the concrete type in the state function. 您可以传递*void指针并将其强制转换为状态函数中的具体类型。 All state functions will have the same signature. 所有状态功能将具有相同的签名。 Something like this: 像这样:

// states
struct state1_args {
    int first;
    int second;
};

struct state2_args {
    float first;
    float second;
    float third;
};

void state1(void* state_args) {
    struct state1_args* args = (struct state1_args*)state_args;
    use(args->first);
    ...
}

void state2(void* state_args) {
    struct state2_args* args = (struct state2_args*)state_args;
    use(args->third);
    ...
}

// state pointer
void (*current_state)(void*);

// state logic
if (condition1) {
    current_state = &state_1;
    current_state_args = &args_1;
} else if (condition2) {
    current_state = &state_2;
    current_state_args = &args_2;
}

// do the thing
(*current_state)(current_state_args);

Wtih the same signature of your 与您的签名相同

// state pointer
void (*current_state)(int, int);

It is not possible. 这不可能。 You have to change your state signature or some how remove an argument from state3. 您必须更改状态签名,或者更改如何从state3中删除参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM