繁体   English   中英

在 C++ 中声明 function 指针的 typedef

[英]Declaration of a function pointer's typedef in C++

我知道以前有人问过类似的问题和答案 我已经了解了 function 指针的概念及其声明的含义。 以下是我的函数指针示例代码,其中我将 function 指针fp_GetBiggerElement指向 function GetBiggerElement

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

我的理解是, typedef意味着为一个类型定义一个新的定义。 通常, typedef语句需要two-parts (或者说两个参数)

  1. 第一部分是需要新别名的类型

  2. 第二部分是一个新的别名

    typedef unsigned int UnsignedInt; // ^ ^ // (original type) (Alias)

例如,在上面的代码中,第一部分是unsigned int ,第二部分是UnsignedInt

    typedef     char *              CharPtr;
    //              ^                   ^                       
    //      (original type)          (Alias)

同样,在上面的第二个示例中,第一部分是char* ,第二部分是CharPtr

问题:我对 function 指针的typedef语句的格式感到困惑。 在语句typedef int(*fp_GetBiggerElement)(int, int); ,然后不遵循typedef的典型双参数格式,它是如何工作的?

更新:我知道 C++11 提供了另一种声明 function 指针的方式,即(通过using声明)。 在这个问题中,我只想了解函数指针的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*

与 function 指针类似:

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)

顺便说一句,在 C++11 中,您还可以获得typedef的不那么令人困惑(并且更强大)的替代方案 - using . 您应该改用(双关语)它。 只是看看:

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

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

这些部分以某种特殊的方式“混合”(有些人称之为“wtf?”) - 变量声明与其使用具有相同的形式,这简化了解析器并允许在编译器中重用代码。

如果您以更“老派”的方式阅读会更有意义:

int *p;

*p是一个int
(等价翻译:“ p是指向int的指针”)

int *p, x;

" *px都是int s"
(“ p是指向int的指针,而xint ”)

int (*q)[3];

*q是一个由三个int组成的数组”,或者“ (*q)[x]是一个int
(" q是一个指向三个int s 数组的指针")

int (*fp)(int,int);

" *fp是一个 function ,它接受两个int并返回一个int "
(“ fp是指向 function 的指针,它接受两个int并返回一个int ”)

int (*(*foo)())[3];

*(*foo)()是一个由三个int组成的数组”(或者,“ (*(*foo)())[x]是一个int ) - 或者,换句话说,
" (*foo)()是一个指向三个int数组的指针" - 或者,换句话说,
foo是一个指向 function 的指针,它不接受 arguments 并返回一个指向三个int s 数组的指针”

一个有点难以理解的效果是

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

一次性声明以上所有内容。

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

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; )。

function 指针非常相似:

int (*fp) (int, int);

我有一个变量fp ,如果我取消引用它,我会得到int (int, int) typedef相同的模式。 另一方面,用于定义别名的(新)C++ 方式更好地反映了 C++ 的思维方式:

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

我有一个变量,它的类型从一开始就是一个指针(指向任何东西)——嗯,不是完全一致的,但是:使用 C++ 的思维方式,function 指针可能看起来像int(int, int)*或者可能需要括号(int(int, int))* ,但是好的,这不是它的方式(希望与 C 保持兼容是原因)。

typedef声明类似于简单声明,但不是将声明符的标识符声明为 object 或 function 的标识符,而是将声明符的标识符声明为指定类型的别名。

考虑以下简单声明的示例

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

他们声明了几个对象和 function h

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM