zjn*_*yly 2 c c++ typedef function-pointers declaration
我认为通常 typedef 可以这样使用:
typedef int INT
Run Code Online (Sandbox Code Playgroud)
第一个单词是 C/C++ 中的某个关键字,第二个单词是第一个单词的别名。
但最近我注意到这个说法
typedef void (*GL_GENBUFFERS) (GLsizei, GLuint*);
GL_GENBUFFERS glGenBuffers = (GL_GENBUFFERS)wglGetProcAddress("glGenBuffers");
GLuint buffer;
glGenBuffers(1, &buffer);
Run Code Online (Sandbox Code Playgroud)
看起来typedef后面有三个单词,那么编译器如何解析这个语句呢?
谢谢!
让我们首先讨论一般的声明语法(我将使用 C 术语,尽管 C++ 非常相似)。在 C 和 C++ 中,声明包含一系列一个或多个声明说明符,后跟零个或多个声明符的逗号分隔列表。
声明说明符包括类型说明符(int
、double
、char
、unsigned
等)、类型限定符(const
、volatile
等)、存储类说明符(static
、register
、typedef
等)struct
和union
说明符,以及一些其他我们不会在这里讨论的东西。
声明符包括所声明的事物的名称,以及有关该事物的指针性、数组性或函数性的信息(在 C++ 中,您还具有引用性)。
当你声明一个函数时,例如
void foo( int, double );
Run Code Online (Sandbox Code Playgroud)
void
是声明说明符(类型说明符),foo( int, double )
是声明符。的类型foo
完全由声明说明符和声明符的组合指定:
foo -- foo
foo( ) -- is a function taking
foo( ) -- unnamed parameter
foo( int ) -- is an int
foo( int, ) -- unnamed parameter
foo( int, double ) -- is a double
void foo( int, double ) -- returning void
Run Code Online (Sandbox Code Playgroud)
用简单的英语来说, 的类型foo
是“带有int
和double
参数并返回 的函数void
”。
您也可以声明指向函数的指针:
fptr -- fptr
(*fptr) -- is a pointer to
(*fptr)( ) -- function taking
(*fptr)( ) -- unnamed parameter
(*fptr)( int ) -- is an int
(*fptr)( int, ) -- unnamed parameter
(*fptr)( int, double ) -- is a double
void (*fptr)( int, double ) -- returning void
Run Code Online (Sandbox Code Playgroud)
同样,唯一的声明说明符是void
,声明符是(*fptr)( int, double )
。
出于语法目的,与存储类说明符 ( 、、 )typedef
分组,但它的行为与其他存储类说明符不同 - 它不会影响所声明事物的存储或可见性,而是使声明符中的标识符成为别名 对于类型。如果我们坚持上面声明的前面:static
auto
register
typedef
typedef void (*fptr)( int, double );
Run Code Online (Sandbox Code Playgroud)
那么它读作
fptr -- fptr
typedef fptr -- IS AN ALIAS FOR THE TYPE
typedef (*fptr) -- pointer to
typedef (*fptr)( ) -- function taking
typedef (*fptr)( ) -- unnamed parameter
typedef (*fptr)( int ) -- is an int
typedef (*fptr)( int, ) -- unnamed parameter
typedef (*fptr)( int, double ) -- is a double
typedef void (*fptr)( int, double ) -- returning void
Run Code Online (Sandbox Code Playgroud)
IOW是“指向带有和参数并返回的函数的指针”类型的fptr
别名(名称) ,您可以使用它来声明该类型的指针对象:typedef
int
double
void
fptr fp1, fp2;
Run Code Online (Sandbox Code Playgroud)
您可以对其他指针类型1执行相同的操作:
typedef int *intp; // intp is an alias for the type "pointer to int";
typedef double (*arr)[10]; // arr is an alias for the type "pointer to 10-element array of double"
Run Code Online (Sandbox Code Playgroud)
声明符可能会变得相当复杂。您可以拥有指向函数的指针:
T (*ptr)();
Run Code Online (Sandbox Code Playgroud)
指向数组的指针:
T (*ptr)[N];
Run Code Online (Sandbox Code Playgroud)
函数指针数组:
T (*ptr[N])();
Run Code Online (Sandbox Code Playgroud)
返回数组指针的函数:
T (*foo())[N];
Run Code Online (Sandbox Code Playgroud)
指向返回数组指针的函数的指针数组:
T (*(*arr[N])())[M];
Run Code Online (Sandbox Code Playgroud)
等等,坚持typedef
在其中任何一个前面都会起作用:
typedef T (*(*arr[N])())[M];
Run Code Online (Sandbox Code Playgroud)
meansarr
是“N 元素指针数组,该函数返回 M 元素数组的指针T
”类型的别名。
*
或尝试打印其值与%p
或类似的东西)。