【问题标题】:difference between function pointer and function name函数指针和函数名的区别
【发布时间】:2017-11-03 23:00:45
【问题描述】:

什么是函数名?它与指向它的指针有什么关系?为了尝试理解这些问题,编写了以下代码:

#include <stdio.h>

int testFunc(void);

void ptrFuncProp(void);

int main(){
    ptrFuncProp();
    return 0;
}

void ptrFuncProp(void){
    int i = 0;
    int (*p_testFunc)(void) = testFunc;

    testFunc();
    (*testFunc)();
    p_testFunc();
    (*p_testFunc)();

    printf("testFunc:\t%d\n*testFunc:\t%d\n",sizeof(testFunc),sizeof(*testFunc));
    printf("p_testFunc:\t%d\n*p_testFunc:\t%d\n",sizeof(p_testFunc),sizeof(*p_testFunc));
    putchar('\n');

    printf("testFunc:\t%c\n",testFunc);
    printf("*testFunc:\t%c\n",*testFunc);
    printf("*p_testFunc:\t%c\n",*p_testFunc);

    for(;*p_testFunc && i<30;i++){
        printf("%c ",*(p_testFunc + i));
        if(i%10 == 9){
            putchar('\n');
        }
    }
}

int testFunc(void){
    int i=0;
    printf("output by testFunc\n");
    return 0;
}

输出如下:

output of the program

在代码中,定义了一个简单的函数testFunc,并有一个指针p_testFunc指向它。我在网上了解到,我尝试了四种方法来调用这个函数;它们都可以工作,虽然我不太明白。

接下来的两行试图弄清楚函数名和它的指针到底是什么。我能理解的一点是 p_testFunc 是一个指针,所以它包含其他东西的地址;地址是 8 个字节。但是为什么函数名的大小是1字节,因为我以前认为函数名是一个const指针,其内容是函数的开始地址。如果函数名不是指针,怎么解引用?

实验结束后,问题仍未解决。

【问题讨论】:

  • printf("%c ",*(p_testFunc + i)); 是 UB,如果我没记错的话。
  • @SouravGhosh 你不是。 stackoverflow.com/questions/5085366/…
  • 函数 name 是编译器和链接器的标识符。函数 pointer 指向一个函数,与它的名称无关(如果正确声明,函数指针将要求只有 [the address of] 兼容函数分配给它)。通过调用函数指针来取消引用它(编译器会为您取消引用它)。
  • 您使问题复杂化了。大多数函数都是直接调用的。有时需要在函数和调用者之间插入一个间接层,即函数指针。像其他指针一样,它包含一个地址。与其他指针不同,您不需要 * 来取消引用它。
  • 可能对我目前的学习阶段来说太深了。

标签: c function pointers


【解决方案1】:

如果你刚接触 C,你应该首先掌握指针是什么。

"指针是一个变量,它的值是另一个变量的地址,即内存位置的直接地址。和任何变量或常量一样,你必须在使用它之前声明一个指针来存储任何变量地址”。

指向整数/字符等的指针和指向函数的指针之间没有区别。它的目的是指向内存中的一个地址,在这种情况下,函数被存储。

另一方面,函数的名称就是函数的命名方式。正如人们在 cmets 中建议的那样,它识别了编译器、链接器前面的函数。

如何定义函数:

int ( what the function will return) isEven (the function name) (int number) ( what argument will it accept)
//How it would look like
int isEven (int number){

   //Here goes the body!

}

只是对函数的一点概述。

指针函数是如何定义的:

int (return type) *(*isEven(Name))(int(input arguments));
//No tips again!
int  (*isEven)(int);

我还注意到在您的代码中您没有使用任何 &。 考虑以下片段的结果:

    #include <stdio.h>
void my_int_func(int x)
{
    printf( "%d\n", x );
}

int main()
{
    void (*foo)(int);
    /* the ampersand is actually optional */
    foo = &my_int_func;
    printf("addres: %p \n", foo);
    printf("addres: %p \n",  my_int_func);


    return 0;
}

注意:%p 会格式化你输入的地址。

【讨论】:

  • 我用%p再次输出地址,证明都是同一个地址。但是如何在源代码中解释 sizeof 的结果。 printf("testFunc:\t%p\n",testFunc); printf("*testFunc:\t%p\n",*testFunc); printf("p_testFunc:\t%p\n",p_testFunc); printf("*p_testFunc:\t%p\n",*p_testFunc);
  • 你用的是什么编译器?还请解释一下您对输出感到惊讶的地方,以便我能够更好地解释它。
  • 我对编译器知之甚少,但我使用的软件是win8.1中的dev-C++。令我惊讶的是函数名称的大小为 1,而指向函数的指针的大小为 8,正如您在我在原始问题中提供的图表中所见,尽管它们代表(或指向)的地址相同,即函数的开始。
  • @Paul Ogilvie 的评论说函数名是一个标识符;标识符是否只有 1 个字节导致 sizeof 操作的结果?
  • 函数name是标识符。指针大小差异很大,这取决于您的 IDE、编译器、操作系统。大小也取决于指向的变量。这应该是一本好书:link如果您有更多问题,请不要犹豫,如果您发现我的 cmets 有帮助,请支持/接受我的回答 :)
猜你喜欢
  • 1970-01-01
  • 2012-10-03
  • 2022-10-16
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
相关资源
最近更新 更多