c函数指针和用户定义的函数标识符冲突

c function pointer & user defined function identifier collision

我测试了这个简单的函数指针程序

#include <stdio.h>
#include <conio.h>
void ptr();
void fun()
{
    printf("fun() is called\n");
}
void ptr()
{
    printf("ptr() is called\n");
}
int main()
{
  void(*ptr)();
  ptr=fun;
  ptr();        // Why it works fine?
  //(ptr)();
  void(*a)()=fun;
  (*a)();
  _getch();
  return 0; 
}

输出:

fun() is called

fun() is called

我有一个问题,为什么函数调用语句 指针(); 不会调用用户定义的函数 ptr(),而是调用 fun() 函数? 为什么不需要 ptr 周围的括号? 我的程序需要进行哪些更改,以便我的程序显示如下输出。

ptr() is called

fun() is called

当您在 main 中定义局部变量 ptr 时,它 shadows 同名函数 ptr 是全局的。所以当你调用ptr()时,调用的是局部函数指针ptr

要调用函数ptr,您需要确保局部变量ptr超出范围,如这个人为示例:

int main()
{
    {
      void(*ptr)();
      ptr=fun;
    }
    ptr();
}

它是通常范围规则的应用;局部变量隐藏了同名的全局变量。

或者,更准确地说,在内部作用域中定义的变量隐藏了任何外部作用域中的同名变量。

范围基本上由围绕语句块的大括号组控制(稍微简化)。

您可以通过 -Wshadow.

让 GCC 警告您此类问题

问题的另一部分是您可以通过指向函数的指针以(至少)两种方式调用函数:

(*ptr_to_function)();    // Pre-standard notation
ptr_to_function();       // Notation allowed by standard C

因此调用 ptr(); 与程序中的 (*ptr)(); 相同。


What changes does my program require to display:

ptr() is called
fun() is called

最简单的更改是删除行 void (*ptr)() = fun;

你也可以这样做:

#include <stdio.h>

void fun(void)
{
    printf("fun() is called\n");
}
void ptr(void)
{
    printf("ptr() is called\n");
}
int main(void)
{
  void (*xyz)(void) = ptr;
  void (*ptr)(void) = fun;
  xyz();
  ptr();
  return 0; 
}