[英]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
(或者说两个参数)
第一部分是需要新别名的类型
第二部分是一个新的别名
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;
" *p
和x
都是int
s"
(“ p
是指向int
的指针,而x
是int
”)
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 );
也就是说x
是int
类型的别名。 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.