什么是函数指针的语法在C目的是什么? [英] What is the purpose of Function Pointer syntax in C?

查看:162
本文介绍了什么是函数指针的语法在C目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:它已经指出,这个问题是有点混乱。短的版本是:为什么有一个单独的指针变量(例如, fnPtr ),它指向一个函数(例如, FN )时,函数名 FN 本身不带参数,已经是一个指针?/编辑

我想了解的东西,可以使用方关于函数指针社区的反馈。 (虽然这可能看起来像关于该主题的其他问题重复,真的不是,因为至少不是我能找到。)

我明白一个指向函数的概念,被用来作为参数传递给另一个函数作为回调...即告诉 FN1 使用 FN2 在某种程度上 FN1 的执行过程中。我不明白的是在这一切正在使用的复杂的语法。如果 FN 是一个定义的函数,然后调用 FN(...)将与提供的参数执行的功能。然而,单独使用 FN 是该函数的地址,即,一指针的功能。此外, FN &放大器; FN * FN 都是同样的事情。为什么有专门的函数指针,为什么创造新的变量(即 fnPtr ),它指向一个功能...函数名已经是自己的指针!

这code编译并同每一次的作品。

 的#include<&stdlib.h中GT;
#包括LT&;&stdio.h中GT;INT FN(INT VAR){// FN是一个函数,它接受一个int并返回一个int
    返回VAR;
}INT(* fnPtrAmp)(INT)=安培; FN;
INT(* fnPtr)(INT)= FN;INT needsCallback(int变量,INT回调(INT)){
    返回回调(可变);
}INT needsCallbackPointer(int变量,INT(* callbackPtr)(INT)){
    返回callbackPtr(可变);
}INT needsCallbackPointerWithDereference(int变量,INT(* callbackPtr)(INT)){
    返回(* callbackPtr)(可变);
}诠释主(){
    的printf(%d个\\ N,FN(4));
    的printf(%d个\\ N,fnPtr(4));
    的printf(%d个\\ N,(* fnPtr)(4));
    的printf(%d个\\ N,needsCallback(4,FN));
    的printf(%d个\\ N,needsCallbackPointer(4 fnPtr));
    的printf(%d个\\ N,needsCallbackPointer(4,FN));
    的printf(%d个\\ N,needsCallbackPointer(4,&安培; FN));
    的printf(%d个\\ N,needsCallbackPointerWithDereference(4 fnPtr));
    的printf(%d个\\ N,needsCallbackPointerWithDereference(4,FN));
    的printf(%d个\\ N,needsCallbackPointerWithDereference(4,&安培; FN));
    返回0;
}

最简单的语法是 needsCallback ,但是未在任何地方进行,它总是 needsCallbackPointer fnPtrAmp 。为什么?随着 needsCallback 您甚至不必定义一个额外的变量是函数指针。正如我之前所说的,函数名是它自己的指针!

可以使用一些反馈...感谢。


解决方案

  1. 函数指针变量是有用的,当跟随后来的控制流修改函数指针(例如选择一个不同的回调)。

    与运行时处理的结合,你不知道在编译时的功能,而是在运行时使用则dlsym 函数指针变量也有用C>。这通常是在可扩展的API(OpenGL是该方案的一个普通用户,例如)和插件的情况下使用。


  2. 的最简单的语法是needsCallback的但不是在任何地方进行,它总是needsCallbackPointer和fnPtrAmp为什么?:有与如何一个变量或typedef声明一致的函数的参数的声明会是什么样子。


  3. 你问另一个问题是,为什么 * fnPtr 的作品,为什么括号

    那么,括号是必需的,因为该函数调用运算符()具有更高的precedence比引用操作 * ,因此该函数先调用,然后返回值derefenced。 (* fnPtr)()工程解决这一问题。


  4. someFunction &放大器; someFunction 不是由于功能是等价的在C是一等公民(函数是不是可以被操纵,像正常的对象 INT ,例如),但函数指针。因此,一个函数的名字总是和内在转化为函数指针,以该名称引用的函数。请注意,您可以申请&放大器;多次一个函数指针,产生一个指向函数的指针,指针的指针的函数指针等。因此,它不以行为像感 * 呢,你可以在一个函数指针经常你想要使用。


  5. * fnPtr 的作品,因为 * 运营商在使用函数指针本质上产生完全相同的指针。同样的理由为4) - 有在语言中没有函数对象。因此,你不能得到一个函数的名字从一个函数指针回来了,不可能的。


我不知道为什么这些运营商是为函数名和指针分别定义。也许历史的原因?对于使用其他指针类型一致性?

我怀疑是运营商少的语法被介绍以后,以节省打字,因为你不能在没有右值,也不左值范围内使用有意义的函数名称。由于孤单没有什么人可以用函数指针要么做(除了各地传递它,当然你可以改变它,就像 fnPtr ++;?但是,这是否让你),它使得相当多的感觉,添加隐式转换使 fnPtr()可能,节省再次输入。

(最后两段是我的一部分纯粹的投机行为。)

EDIT: It's been pointed out that this question is sort of confusing. The short version is: "why have a separate pointer variable (eg, fnPtr) which points to a function (eg, fn) when the function name fn itself, without arguments, is already a pointer? /EDIT

I'm trying to understand something and could use feedback from the community regarding function pointers. (And while this might look like a duplicate of other questions on the topic, it really isn't, as least not that I could find.)

I understand the concept of a pointer to a function being used as an argument to another function as a callback...ie telling fn1 to use fn2 in some way during the execution of fn1. What I don't understand is the complex syntax being used in all of it. If fn is a defined function, then calling fn(...) will execute the function with the supplied arguments. However, fn used on its own is the address of the function, that is, a pointer to the function. Furthermore, fn, &fn, and *fn are all the same thing. Why have dedicated function pointers, and why create new variable (ie, fnPtr) which point to a function...the function name is already its own pointer!

This code compiles and works the same every time.

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

int fn(int var) { //fn is a function which takes an int and returns an int
    return var;
}

int (*fnPtrAmp)(int) = &fn;
int (*fnPtr)(int) = fn;

int needsCallback(int variable, int callback(int)) {
    return callback(variable);
}

int needsCallbackPointer(int variable, int (*callbackPtr)(int)) {
    return callbackPtr(variable);
}

int needsCallbackPointerWithDereference(int variable, int (*callbackPtr)(int)) {
    return (*callbackPtr)(variable);
}

int main() {
    printf("%d\n", fn(4));
    printf("%d\n", fnPtr(4));
    printf("%d\n", (*fnPtr)(4));
    printf("%d\n", needsCallback(4,fn));
    printf("%d\n", needsCallbackPointer(4,fnPtr));
    printf("%d\n", needsCallbackPointer(4,fn));
    printf("%d\n", needsCallbackPointer(4,&fn));
    printf("%d\n", needsCallbackPointerWithDereference(4,fnPtr));
    printf("%d\n", needsCallbackPointerWithDereference(4,fn));
    printf("%d\n", needsCallbackPointerWithDereference(4,&fn));
    return 0;
}

The simplest syntax is that of needsCallback but that isn't done anywhere, it's always needsCallbackPointer and fnPtrAmp. Why? With needsCallback you don't even have to define an extra variable to be the function pointer. As I said before, the function name is its own pointer!

Could use some feedback...thanks.

解决方案

  1. Function pointer variables are useful when control flow that follows later on modifies the function pointer (e.g. chooses a different callback).

    Function pointer variables are also useful when dealing with runtime binding, where you do not know the function at compile time but rather assign a function pointer at runtime, for example by using dlsym. This is often used in the context of extensible APIs (OpenGL is a popular user of this scheme, for example) and plugins.

  2. "The simplest syntax is that of needsCallback but that isn't done anywhere, it's always needsCallbackPointer and fnPtrAmp. Why?": to have the declaration in the parameter of a function consistent with how an variable or typedef declaration would look like.

  3. Another question you ask is why *fnPtr works, and why the parentheses.

    Well, the parentheses are required, because the function call operator () has a higher precedence than the dereference operator *, thus the function is first called and then the return value is derefenced. (*fnPtr)() works around that.

  4. someFunction and &someFunction are equivalent due to functions not being first-class citizens in C (functions are not normal objects that can be manipulated, like an int, for example), but function pointers are. Thus a function name is always and inherently converted to a function pointer to the function referenced by that name. Note that you can apply & multiple times to a function pointer, yielding a pointer to function pointer, pointer to pointer to function pointer etc.. Thus it does not behave in a sense like * does, which you can use as often as you want on a function pointer.

  5. *fnPtr works, because the * operator used on a function pointer essentially yields the exact same pointer. Same rationale as 4) - there are no function objects in the language. Thus you cannot get a function name back from a function pointer, not possible.

I don't know why the these operators were defined for function names and pointers, respectively. Maybe historic reasons? For consistency with other pointer types?

I suspect that the operator-less syntax was introduced later on to save typing, since you can't use a function name neither in an rvalue nor lvalue context meaningfully. Since theres nothing one can do with a function pointer either (except passing it around. You can of course change it, like fnPtr++; but where does that get you?), it makes quite a lot of sense to add the implicit conversion making fnPtr() possible, to save typing yet again.

(The last two paragraphs are pure speculation on my part.)

这篇关于什么是函数指针的语法在C目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆