Typedef函数vs函数指针

时间:2017-05-24 03:22:48

标签: c++ c function-pointers declaration

我正在尝试使用typedef来理解函数声明。

这段代码在C ++中做了什么?

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

fcn_t f;
fcn_t *pf;
ptr_t pf2;

根据我的理解:

  • fcn_t是函数的类型,因此带有f的行是函数声明(不是定义),我以后可以将它定义为{ {1}}就像我宣布void f(void) { blabla(); bleble(); }而不是void f(void);一样;
  • fcn_t f;是函数指针的类型,fcn_t *的行是指针变量 definition pf是默认初始化的(假设代码摘录来自全球范围);
  • pffcn_t*之间没有区别,因此我所说的关于ptr_t的所有内容都适用于pf

我做对了吗?如果我将它们标记为pf2,那三个声明中的任何一个都会改变它的含义吗?如果代码编译为C而不是C ++,会发生什么变化?

2 个答案:

答案 0 :(得分:3)

是的,你在所有三个方面都是正确的。如果你标记它们extern,唯一会改变的是函数指针。函数声明在C ++中默认为extern

尝试并编译以下程序

template <typename...>
struct WhichType;

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

// constexpr auto one = WhichType<fcn_t>{};
// constexpr auto two = WhichType<fcn_t*>{};
// constexpr auto three = WhichType<ptr_t>{};

fcn_t f;

void f() {}

int main() {
    f();
}

取消注释注释行可能会给您一个编译器错误,告诉您实例化WhichType实例的类型,因此它应该显示您询问的所有三件事的确切类型。这是我从Scott Meyers的书“Effective Modern C ++”中汲取的一个技巧。

要测试声明是否为extern,请编写两个简单的实现文件,其中一个包含变量的定义

<强>的main.cpp

template <typename...>
struct WhichType;

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

fcn_t f;

int main() {
    f();
}

<强> definition.cpp

void f() {}

然后编译,链接并运行definition.cppmain.cpp(通过g++ -std=c++14 definition.cpp main.cpp然后./a.out)。如果声明不是extern,那么编译将失败并出现未定义的符号错误。

答案 1 :(得分:-1)

以下是这些typedef

的简单说明
#include <stdio.h>

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

fcn_t f;
fcn_t *pf;
ptr_t pf2;

void
f(void)
{
  printf("I am void\n");
}

void 
vSayHi(void)
{
   printf( "Hi\n" );
}

int
main(void)
{

   pf2 = vSayHi;
   pf2();

   pf = vSayHi;
   pf();

   f();

   return 0;
}

输出:

Hi
Hi
I am void