C++ 函数指针的声明';s typedef在C+中+;

C++ 函数指针的声明';s typedef在C+中+;,c++,typedef,C++,Typedef,我知道以前也有人问过类似的问题。我已经理解了函数指针的概念及其声明的含义。下面是我的函数指针示例代码,其中我将函数指针fp_getbiggerement指定给函数getbiggerement #include <iostream> typedef int (*fp_GetBiggerElement) (int, int); // ^ ^ ^

我知道以前也有人问过类似的问题。我已经理解了函数指针的概念及其声明的含义。下面是我的函数指针示例代码,其中我将函数指针
fp_getbiggerement
指定给函数
getbiggerement

    #include <iostream>

    typedef     int     (*fp_GetBiggerElement)      (int, int);
    //           ^                ^                     ^
    //      return type      type name              arguments

    using namespace std;

    int GetBiggerElement(int arg1, int arg2)
    {
        int bigger = arg1 > arg2 ? arg1 : arg2;
        return bigger;
    }

    int main()
    {
        fp_GetBiggerElement funcPtr = GetBiggerElement;

        int valueReturned = funcPtr(10, 20);
        cout << valueReturned << endl;
        return 0;
    }
例如,在上面的代码中,第一部分是
unsigned int
,第二部分是
unsigned int

    typedef     char *              CharPtr;
    //              ^                   ^                       
    //      (original type)          (Alias)
类似地,在上面的第二个示例中,第一部分是
char*
,第二部分是
CharPtr

问题:我对函数指针的
typedef
语句的格式感到困惑。在语句
typedefint(*fp_getbiggerement)(int,int)中
,没有遵循
typedef
的典型双参数格式,它是如何工作的


更新:我知道C++11提供了另一种声明函数指针的方法,即(通过
使用
station)。在这个问题中,我只想了解函数指针的
typedef
语句的语法。

我认为考虑
typedef
语法的最好方法就像声明您想要typedef类型的变量一样。例如:

char *CharPtr;// declare CharPtr to be variable of type char*

typedef char *CharPtr_t;// declare CharPtr_t to be alias of type char*
与函数指针类似:

int (*fp) (int, int);// declare fp as pointer to int(int, int)

typedef int (*fp_t)(int, int);// declare fp_t to be alias of pointer to int(int, int)
int (*fp) (int, int);
顺便说一句,在C++11和更高版本中,您可以使用
typedef
-
来替代
。你应该改用(双关语)它。看看:

using fp = int (*)(int, int);// declare fp_t to be alias of pointer to int(int, int)

这只是函数指针的语法。 如果你只声明一个变量,你会看到同样的事情

int foo; // Normal
int (*bar)(int, int); // bar is of type int(*)(int,int)
就我个人而言,我更喜欢使用
using=…
,这在我看来更清楚

using fp_GetBiggerElement = int (*)(int,int);

此语法来自读取变量的C方式

有没有想过为什么我们要在一个表达式中声明的每个指针都需要一个星号

int *p1, *p2, p3; // p3 is not a pointer
C++的人通常倾向于看到一个具有特定类型的变量,它可以是指针(换句话说,他们将指针特性视为该类型的属性)。这就是为什么他们通常喜欢写作

int* p1; // notice asterisk grouped with type
C人们的理解是:我有一个变量
p1
,如果我取消引用它,我会得到类型
int
(因此
p1
作为一个指针是推断信息,也就是说,他们把指针特征看作是变量的属性;这就是为什么他们宁愿将星号分组到名称:
int*p1;

函数指针非常类似:

int (*fp) (int, int);// declare fp as pointer to int(int, int)

typedef int (*fp_t)(int, int);// declare fp_t to be alias of pointer to int(int, int)
int (*fp) (int, int);
我有一个变量
fp
,如果我取消引用它,就会得到
int(int,int)
。与
typedef
的模式相同。另一方面,定义别名的(C++)方式反映了C++思想的更好:

using fp = int (*)(int, int);

我有一个变量,它的类型从一开始就是一个指针(对于任何东西)——但是,不是完全一致的,但是,用C++的思维方式,函数指针可能看起来像“代码> int(int,int)*/c>或者可能需要括号<代码>(int(int,int))*/c>,但是行,不是这样的。(希望与C保持兼容是原因)。

typedef
使用与变量声明相同的语法,但声明的是类型名而不是变量名

这些部分以一种有点奇怪的方式(有些人称之为“wtf”)进行“混合”——变量声明的形式与其使用形式相同,这简化了解析器并允许在编译器中重用代码

如果你以一种更“老派”的方式阅读,这会更有意义:

*p
是一个
int

(等效翻译:“
p
是指向
int
”的指针)

*p
x
都是
int
s”
(“
p
是指向
int
的指针,
x
int
”)

*q
是三个
int
s的数组”,或者“
(*q)[x]
int

(“
q
是指向三个
int
s的数组的指针”)

*fp
是一个函数,它接受两个
int
s并返回一个
int

(“
fp
是指向函数的指针,该函数接受两个
int
s并返回一个
int
”)

*(*foo)(
是三个
int
s的数组”(或者,
(*(*foo)()[x]
int
)-或者换句话说,
(*foo)(
是指向三个
int
s”数组的指针”-或者换句话说,
foo
是指向函数的指针,该函数不带任何参数,并返回指向三个
int
s数组的指针”

这有点难以理解的效果是

int *p, x, (*q)[3], (*fp)(int,int), (*(*foo)())[3];

一次声明上述所有内容。

typedef
声明类似于简单声明,但它们不是将声明器的标识符声明为对象或函数的标识符,而是将声明器的标识符声明为指定类型的别名

考虑以下简单声明的示例

int x;
unsigned int a[10][20];
int unsigned ( *p )[10][20];
void ( *f )( int, int );
double h( double ); 
它们声明了几个对象和函数
h

现在将decl说明符
typedef
(以相对于其他decl说明符的任何顺序)放入这些声明中,您将得到声明的标识符成为类型的别名

typedef int x;
unsigned typedef int a[10][20];
int unsigned typedef ( *p )[10][20];
void typedef ( *f )( int, int );
typedef double h( double ); 

也就是说,
x
是类型
int
的别名
a
是类型unsigned
int[10][20]
的别名
p
是指针类型unsigned
int(*)[10][20]
f
是函数指针
void(*)(int,int)的别名
h
在函数类型的别名中
double(double)

可能重复:@PaulR:这是同一个问题,我在OP中发布了它的链接,但它没有回答我的问题。@skm更准确地说,它不是
ty的语法
int (*(*foo)())[3];
int *p, x, (*q)[3], (*fp)(int,int), (*(*foo)())[3];
int x;
unsigned int a[10][20];
int unsigned ( *p )[10][20];
void ( *f )( int, int );
double h( double ); 
typedef int x;
unsigned typedef int a[10][20];
int unsigned typedef ( *p )[10][20];
void typedef ( *f )( int, int );
typedef double h( double );