简体   繁体   English

C ++中的函数指针歧义

[英]Function Pointer ambiguity in C++

I have two questions : 我有两个问题:

Q1) Are the function names themselves pointers ?? Q1)函数名称本身是指针吗?

If they are pointers , then what values are stored in them? 如果它们是指针,那么它们中存储了什么值?

Else if they are not pointers ,then, what are they and what values are stored in them? 否则,如果它们不是指针,那么它们是什么以及它们中存储了什么值?

If we consider that function names are pointers. 如果我们认为函数名是指针。 Then : 然后 :

void display(){...}

int main ()
{ 
    void (*p)();

    **p=display; //Works (justified**, because we are assigning one pointer into another)

    **p=&display; //Works (Not justified** If function name is a pointer (let say type*) , then &display is of datatype : type**. Then how can we assign type** (i.e. &display) into type * (i.e. p)??)

    **p=*display; //Works (Not justified** If function name is a pointer ( type *) ,then, how can we assign type (i.e. *display) into type * (i.e. p) ?? )
}

Again , 再次,

cout<<display<<";"<<&display<<";"<<*display;

Prints something like : 打印类似于:

0x1234;0x1234;0x1234 为0x1234;为0x1234; 0x1234的

[1234 is just for example] [1234只是例如]

[OMG! [我的天啊! How is this possible ?? 这怎么可能 ?? How can address of a pointer, address it is pointing to and the value at pointed address all be same? 如何指向指针的地址,指向的地址和指向地址的值都相同? ] ]

Q2) What value is stored in a user defined pointer to a function ? Q2)用户定义的函数指针中存储了什么值?

Consider the example : 考虑这个例子:

void display(){...}

int main()
{
    void (*f)();

    f=display;

    f=*f; // Why does it work?? How can we assign type (i.e. *f ) into type * (i.e.  f). 

    cout<<f<<";"<<&f<<";"<<*f;

    //Prints something like :

    0x1234;0x6789;0x1234
}

[First two outputs are justified... But how can the value in a pointer (address it is pointing to) be equal to the value stored in the pointed address? [前两个输出是合理的...... 但是指针(它指向的地址)中的值如何等于存储在指向地址中的值? ] ]

Again : 再次:

f=*********f; // How can this work?

I searched it online but all info that is available is regarding usage and example code to create function pointers. 我在网上搜索了它,但所有可用的信息都是关于用法和示例代码来创建函数指针。 None of them say about what they are or how they are different from normal pointers. 他们都没有说出他们是什么或者他们与普通指针的区别。

So I must be missing something very basic thing. 所以我必须遗漏一些非常基本的东西。 Please point me out what I am missing. 请指出我缺少的东西。 (Sorry for my ignorance being a beginner.) (抱歉我的初学者是无知的。)

Are the function names themselves pointers? 函数名称本身是指针吗?

No. However, in some contexts, a function can be automatically converted to a pointer-to-function. 不可以。但是,在某些情况下,函数可以自动转换为指向函数的指针。 The standard says in paragraph 4.3: 该标准在第4.3段中说明:

An lvalue of function type T can be converted to a prvalue of type “pointer to T.” The result is a pointer to the function. 函数类型T的左值可以转换为“指向T的指针”的prvalue。结果是指向函数的指针。

(A function name designates an lvalue, but there can be other lvalues of function type). (函数名称指定左值,但可以有其他函数类型的左值)。

In your examples 在你的例子中

p = display;
p = *p;

there's exactly this kind of automatic conversion. 正是这种自动转换。 display and *p are lvalues of a function type, and when needed, they are silently and automatically converted to a pointer-to-function type. display*p是函数类型的左值,并且在需要时,它们以静默方式自动转换为指向函数的类型。

p = *display; 

Here the conversion occurs twice : first display is converted to a pointer for the * operator, then it is dereferenced, then converted to a pointer again for the = operator. 这里转换发生两次 :第一次display转换为*运算符的指针,然后取消引用,然后再次转换为=运算符的指针。

cout << display << ";" << &display << ";" << *display;

Here, display is converted to a pointer for operator << ; 这里, display转换为operator <<的指针; &display is already a pointer because & is a normal address-taking operator; &display已经是一个指针,因为&是一个普通的地址获取操作符; and *display is converted to a pointer for operator << while inside it display is converted to a pointer for operator * . *display转换为operator <<的指针,而在其内部display转换为operator *的指针。

f = *********f;

There are many conversions of this kind in this expression. 在这个表达式中有很多这种转换。 Count them yourself! 自己算吧!

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

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