Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我们什么时候使用函数指针_C - Fatal编程技术网

C 我们什么时候使用函数指针

C 我们什么时候使用函数指针,c,C,我试图理解现有的代码 我们什么时候真正开始使用函数指针?特别像下面的那个 struct xx { char *a; (*func)(char *a, void *b); void *b; } struct xx ppp[] = { }; 然后检查sizeof(ppp)/sizeof(*ppp) 我们什么时候采用这种方法?sizeof array/sizeof*array是一种确定数组中有多少个元素的方法。(请注意,它必须是数组而不是指针。)我不确定这与函数指针问题有什么

我试图理解现有的代码

我们什么时候真正开始使用函数指针?特别像下面的那个

struct xx

{
  char *a;

  (*func)(char *a, void *b);

  void *b;

}


struct xx ppp[] = { };
然后检查sizeof(ppp)/sizeof(*ppp)


我们什么时候采用这种方法?

sizeof array/sizeof*array
是一种确定数组中有多少个元素的方法。(请注意,它必须是数组而不是指针。)我不确定这与函数指针问题有什么关系

函数指针用于存储对函数的引用,以便以后调用。关键是函数指针不必总是指向同一个函数。(如果有,您只需按名称引用函数即可。)

下面是一个基于您的代码的示例(尽管如果我知道您的代码应该做什么,我可以提供一个更好的示例)

char *s1 = "String one";
char *s2 = "String two";

void f(char *a, void *b) {
    /* Do something with a and b */
}
void g(char *a, void *b) {
    /* Do something else with a and b */
}

struct xx {
    char *a;
    void (*func)(char *a, void *b);
    void *b;
}

struct xx ppp[] = { {s1, f, NULL}, {s2, g, NULL} };

int main(int argc, char **argv) {
    for (int i = 0; i < (sizeof ppp / sizeof *ppp); i++) {
        ppp[i].func(ppp[i].a, ppp[i].b);
    }
}
char*s1=“字符串一”;
char*s2=“字符串二”;
无效f(字符*a,无效*b){
/*用a和b做点什么*/
}
无效g(字符*a,无效*b){
/*用a和b做点别的*/
}
结构xx{
char*a;
无效(*func)(字符*a,无效*b);
无效*b;
}
结构xx ppp[]={{s1,f,NULL},{s2,g,NULL};
int main(int argc,字符**argv){
对于(int i=0;i<(sizeof ppp/sizeof*ppp);i++){
ppp[i].func(ppp[i].a,ppp[i].b);
}
}

sizeof array/sizeof*array
是一种确定数组中有多少元素的方法。(请注意,它必须是数组而不是指针。)我不确定这与函数指针问题有何关系

函数指针用于存储对函数的引用,以便以后调用。关键是函数指针不必总是指向同一个函数。(如果它指向同一个函数,则可以按名称引用函数。)

下面是一个基于您的代码的示例(尽管如果我知道您的代码应该做什么,我可以提供一个更好的示例)

char *s1 = "String one";
char *s2 = "String two";

void f(char *a, void *b) {
    /* Do something with a and b */
}
void g(char *a, void *b) {
    /* Do something else with a and b */
}

struct xx {
    char *a;
    void (*func)(char *a, void *b);
    void *b;
}

struct xx ppp[] = { {s1, f, NULL}, {s2, g, NULL} };

int main(int argc, char **argv) {
    for (int i = 0; i < (sizeof ppp / sizeof *ppp); i++) {
        ppp[i].func(ppp[i].a, ppp[i].b);
    }
}
char*s1=“字符串一”;
char*s2=“字符串二”;
无效f(字符*a,无效*b){
/*用a和b做点什么*/
}
无效g(字符*a,无效*b){
/*用a和b做点别的*/
}
结构xx{
char*a;
无效(*func)(字符*a,无效*b);
无效*b;
}
结构xx ppp[]={{s1,f,NULL},{s2,g,NULL};
int main(int argc,字符**argv){
对于(int i=0;i<(sizeof ppp/sizeof*ppp);i++){
ppp[i].func(ppp[i].a,ppp[i].b);
}
}
我们什么时候真正开始使用函数指针?特别是像下面这样

struct xx

{
  char *a;

  (*func)(char *a, void *b);

  void *b;

}


struct xx ppp[] = { };
当您想使某些内容更抽象时,可以使用函数指针。 举例来说,假设您的应用程序有一个带有一定数量按钮的图形工具箱,每个按钮对应于特定结构的一个实例

按钮结构可以包含函数指针和上下文:

typedef struct {
    void (*press_button) (void *context);
    void *context;
    /* Here some other stuff */
} Button;
当用户单击按钮时,事件类似于

void event_click (Button *b)
{
    b->press_button(b->context);
}
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
这样做的要点是,您可以对每个按钮始终使用相同的结构:

Button * create_button (void (*callback) (void *), void *context, /* other params */
{
    Button *ret = malloc(sizeof(Button));
    if (ret != NULL) {
        ret->callback = callback;
        ret->context = context;
        /* Assign other params */
    }
    ...
    return ret;
}
所以,当你构建工具箱时,你可能会这样做

void event_click (Button *b)
{
    b->press_button(b->context);
}
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
另外,当您创建一些函数指针时,始终携带一些上下文信息(就像我对结构的
上下文
字段所做的那样)。这允许您避免全局变量,因此您可以获得健壮的可重入代码

注意: 这个方法是很不错的,但是如果你处理C++,你可能喜欢使用面向对象和用抽象类派生替换回调。这样做也不需要携带上下文,因为类会为你做。 在回答第一条评论时进行编辑

我正在读的当前代码与文件IO有关。设置环境变量,在文件之间创建符号链接,将数据从一个文件复制到另一个文件,等等。我不明白为什么我们需要在运行时使用函数指针调用这些函数。我们也可以直接调用它们

事实上,你可以不使用函数指针做你需要做的事情。如果我很好地理解你的问题,你就是在试图理解其他人的代码,也就是在做你用函数指针列出的事情

我个人不使用这个功能,除非我需要它,但如果你在这里发布一些额外的代码,也许我们可以尝试更好地理解它

我们什么时候真正开始使用函数指针?特别是像下面这样

struct xx

{
  char *a;

  (*func)(char *a, void *b);

  void *b;

}


struct xx ppp[] = { };
当您想使某些内容更抽象时,可以使用函数指针。 举例来说,假设您的应用程序有一个带有一定数量按钮的图形工具箱,每个按钮对应于特定结构的一个实例

按钮结构可以包含函数指针和上下文:

typedef struct {
    void (*press_button) (void *context);
    void *context;
    /* Here some other stuff */
} Button;
当用户单击按钮时,事件类似于

void event_click (Button *b)
{
    b->press_button(b->context);
}
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
这样做的要点是,您可以对每个按钮始终使用相同的结构:

Button * create_button (void (*callback) (void *), void *context, /* other params */
{
    Button *ret = malloc(sizeof(Button));
    if (ret != NULL) {
        ret->callback = callback;
        ret->context = context;
        /* Assign other params */
    }
    ...
    return ret;
}
所以,当你构建工具箱时,你可能会这样做

void event_click (Button *b)
{
    b->press_button(b->context);
}
Button * toolbox[N];
toolbox[0] = create_button(function1, (void *)data, ...);
toolbox[1] = create_button(function2, (void *)something, ...);
...
toolbox[N-1] = create_button(functionN, (void *)something_else, ...);
另外,当您创建一些函数指针时,始终携带一些上下文信息(就像我对结构的
上下文
字段所做的那样)。这允许您避免全局变量,因此您可以获得健壮的可重入代码

注意: 这个方法是很不错的,但是如果你处理C++,你可能喜欢使用面向对象和用抽象类派生替换回调。这样做也不需要携带上下文,因为类会为你做。 在回答第一条评论时进行编辑

我正在读的当前代码与文件IO有关。设置环境变量,在文件之间创建符号链接,将数据从一个文件复制到另一个文件,等等。我不明白为什么我们需要在运行时使用函数指针调用这些函数。我们也可以直接调用它们

事实上,你可以不使用函数指针做你需要做的事情。如果我很好地理解你的问题,你就是在试图理解别人的代码,这就是你在函数指针中列出的代码