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

时间:2015-01-05 15:40:49

标签: c function-pointers

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

#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(); 不会调用用户定义的函数ptr(),而是调用fun()函数? 为什么围绕ptr的括号不是必要的? 我的程序需要进行哪些更改,以便我的程序显示输出如下。

ptr() is called

fun() is called

2 个答案:

答案 0 :(得分:4)

ptr内定义局部变量main时,阴影是全局的同名函数ptr。所以当你调用ptr()时,它就是被调用的本地函数指针ptr

要使函数ptr被调用,您需要确保局部变量ptr超出范围,如下所示:

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

答案 1 :(得分:2)

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

或者,更准确地说,内部范围中定义的变量会隐藏任何外部范围内的同名变量。

范围基本上由语句块周围的括号组控制(简化一点)。

你可以让GCC用-Wshadow警告你这些问题。

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

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

因此,通话ptr();与您计划中的(*ptr)();相同。


  

我的程序需要显示哪些更改:

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; 
}