为什么函数指针的定义与任意数量的&符号的工作'和;'或星号“*”? [英] Why do function pointer definitions work with any number of ampersands '&' or asterisks '*'?

查看:121
本文介绍了为什么函数指针的定义与任意数量的&符号的工作'和;'或星号“*”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么做了以下工作?

 无效美孚(){
    COUT<< 富在你身上\\ N!
};诠释主(){
    无效(* p1_foo)()= foo的;
    无效(* p2_foo)()= * foo的;
    无效(* p3_foo)()=&安培; foo的;
    无效(* p4_foo)()= *放大器; foo的;
    无效(* p5_foo)()=&放大器; * foo的;
    无效(* p6_foo)()= ** foo的;
    无效(* p7_foo)()= foo的**********************;    (* p1_foo)();
    (* p2_foo)();
    (* p3_foo)();
    (* p4_foo)();
    (* p5_foo)();
    (* p6_foo)();
    (* p7_foo)();
}


解决方案

有几件这样,让所有运营商的这些组合,以相同的方式工作。

,根本原因所有这些工作都是一个函数(如)隐式转换为一个函数指针。这就是为什么无效(* p1_foo)()= foo的; 被隐式转换为指向自己的指针而该指针被分配到 p1_foo

一元&放大器; 中,当施加于函数时,产生一个指向功能,当它被施加到对象,就像它产生一个对象的地址。对于指向普通函数,这是因为隐函数到函数指针的转换总是多余的。在任何情况下,这是为什么无效(* p3_foo)()=&安培;富;

单目 * ,当应用于一个函数指针,得到所指向的功能,就像它产生的指向的,当它被应用到普通的对象指向一个对象。

这些规则可以组合。考虑你的倒数第二个例子, **富


  • 首先,隐式转换为指针本身和第一个 * 应用到函数指针,产生功能试。

  • 然后,结果再次被隐式转换为指针本身和第二个 * 应用,再次产生功能

  • 据然后隐式转换为一个函数指针再次分配给变量。

您可以根据需要添加尽可能多的 * S,结果总是一样的。越 * S,越多越好。

我们还可以考虑第五个例子,&放大器; * foo的


  • 首先,隐式转换为指向自己的指针;一元 * 应用,产生试。

  • 之后,&安培; 用于,产生一个指向,它被分配给变量。

&放大器; 只能虽然施加到功能,而不是已被转换为函数指针(除非,当然,函数指针是一个功能一个变量,在这种情况下,结果是一个指针到一个指针到一个功能;例如,您可以添加到您的列表无效(** pp_foo)()=&安培; p7_foo;

这就是为什么&放大器;&安培;富不起作用:&放大器;富不是一个函数;它是一个函数指针是一个右值。然而,&放*放*放*放*放*放大器; * foo的会的工作,正如&安培; *** ***放大器;富,因为在这两个前pressions的&安培; 总是被应用到的功能,而不是一个右值函数指针。

还请注意,你并不需要使用一元 * 来使通过函数指针调用;无论(* p1_foo)(); (p1_foo)(); 有同样的结果,因为再功能对函数指针的转换。

Why do the following work?

void foo() {
    cout << "Foo to you too!\n";
};

int main() {
    void (*p1_foo)() = foo;
    void (*p2_foo)() = *foo;
    void (*p3_foo)() = &foo;
    void (*p4_foo)() = *&foo;
    void (*p5_foo)() = &*foo;
    void (*p6_foo)() = **foo;
    void (*p7_foo)() = **********************foo;

    (*p1_foo)();
    (*p2_foo)();
    (*p3_foo)();
    (*p4_foo)();
    (*p5_foo)();
    (*p6_foo)();
    (*p7_foo)();
}

解决方案

There are a few pieces to this that allow all of these combinations of operators to work the same way.

The fundamental reason why all of these work is that a function (like foo) is implicitly convertible to a pointer to the function. This is why void (*p1_foo)() = foo; works: foo is implicitly converted into a pointer to itself and that pointer is assigned to p1_foo.

The unary &, when applied to a function, yields a pointer to the function, just like it yields the address of an object when it is applied to an object. For pointers to ordinary functions, it is always redundant because of the implicit function-to-function-pointer conversion. In any case, this is why void (*p3_foo)() = &foo; works.

The unary *, when applied to a function pointer, yields the pointed-to function, just like it yields the pointed-to object when it is applied to an ordinary pointer to an object.

These rules can be combined. Consider your second to last example, **foo:

  • First, foo is implicitly converted to a pointer to itself and the first * is applied to that function pointer, yielding the function foo again.
  • Then, the result is again implicitly converted to a pointer to itself and the second * is applied, again yielding the function foo.
  • It is then implicitly converted to a function pointer again and assigned to the variable.

You can add as many *s as you like, the result is always the same. The more *s, the merrier.

We can also consider your fifth example, &*foo:

  • First, foo is implicitly converted to a pointer to itself; the unary * is applied, yielding foo again.
  • Then, the & is applied to foo, yielding a pointer to foo, which is assigned to the variable.

The & can only be applied to a function though, not to a function that has been converted to a function pointer (unless, of course, the function pointer is a variable, in which case the result is a pointer-to-a-pointer-to-a-function; for example, you could add to your list void (**pp_foo)() = &p7_foo;).

This is why &&foo doesn't work: &foo is not a function; it is a function pointer that is an rvalue. However, &*&*&*&*&*&*foo would work, as would &******&foo, because in both of those expressions the & is always applied to a function and not to an rvalue function pointer.

Note also that you do not need to use the unary * to make the call via the function pointer; both (*p1_foo)(); and (p1_foo)(); have the same result, again because of the function-to-function-pointer conversion.

这篇关于为什么函数指针的定义与任意数量的&符号的工作'和;'或星号“*”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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