#include <stdio.h>
char * const f1( int n )
{
printf( "f1 called with n = %d\n", n );
return NULL;
}
char *const f2( int n )
{
printf( "f2 called with n = %d\n", n );
return NULL;
}
char *const f3( int n )
{
printf( "f3 called with n = %d\n", n );
return NULL;
}
char *const f4( int n )
{
printf( "f4 called with n = %d\n", n );
return NULL;
}
char *const f5( int n )
{
printf( "f5 called with n = %d\n", n );
return NULL;
}
int main( void )
{
char *const ( *a[5] )( int ) = { f1, f2, f3, f4, f5 };
for (int i = 0; i < 5; i++)
{
a[i]( i );
}
putchar( '\n' );
char *const ( *( *const bar )[5] )( int ) = &a;
for (int i = 0; i < 5; i++)
{
( *bar )[i]( i );
}
}
程序输出为
f1 called with n = 0
f2 called with n = 1
f3 called with n = 2
f4 called with n = 3
f5 called with n = 4
f1 called with n = 0
f2 called with n = 1
f3 called with n = 2
f4 called with n = 3
f5 called with n = 4
2条答案
按热度按时间dojqjjoe1#
让我们一步一步地考虑声明
这部分
声明一个名为
bar
的常量指针,该指针指向一个指针类型的5个元素的数组指向函数类型的指针
这是一个演示程序。
程序输出为
使用typedef声明可以使指针的声明更具可读性。
svdrlsy42#
“反映使用的声明”说:
表达式
*(*(*bar)[0])(0)
给出char
。我们可以继续说:
表达式
(*(*bar)[0])(0)
给出了一个指向char
的指针。所以:
使用(int)参数调用函数
(*(*bar)[0])
将返回指向char
的指针。...解引用
bar
,则数组(大小为5)中的索引在具有(int)参数的函数上具有指针,将返回指向char
的指针。表达式也可以从对象开始解码。在这里,我们以名称
bar
作为开始。但是在一些表达式中,我们没有任何名字,起点是第一个表达式(括号中),它的右边有一个数组[...]或一个函数调用(...)或什么都没有。请注意,要读取表达式,我们首先读取右边的部分(数组和函数),然后在左边完成读取第一部分,然后在左边完成其他部分(指针)。1.查看开始表达式:
(* const bar)
,bar
是常量指针指向...将表达式替换为
bbar
,得到char* const (* bbar[5])(int);
1.看上面的表情:
(* bbar[5])
,bbar
是一个5个指针的数组,指向...将表达式替换为
bbbar
,得到char* const bbbar(int);
1.看上面的表情:
char* const bbbar(int)
,bbbar
是一个接收int
并返回一个指向char
的常量指针的函数。bar
是一个常量指针,指向一个5个指针的数组,指向接收(int
)的函数,返回指向char
的常量指针。在真实的中,我们永远不必这样做,复杂的表达式是
typedef
: