我需要声明一个指向函数的指针数组,如下所示:
extern void function1(void); extern void function2(void); ... void (*MESSAGE_HANDLERS[])(void) = { function1, function2, ... };
但是,我希望将数组声明为常量 - 数组中的数据和指向数据的指针.不幸的是,我不记得在哪里放置const关键字.
我假设在这种情况下,实际指针MESSAGE_HANDLERS已经是常量,因为它被声明为数组.另一方面,如果声明如图所示,那么数组中的函数指针是否可以在运行时更改?
有一种技术可以记住如何构建这种类型.首先尝试从名称开始读取指针并从右向左阅读.
T t[5];
是一个5 T的数组.要使T成为函数类型,请将返回类型写入左侧,将参数写入右侧:
void t[5](void);
将是一个由5个函数组成的数组,返回void并且不带参数.但是函数本身不能填充数组!它们不是对象.只有指向它们的指针才可以.
关于什么
void * t[5](void);
这仍然是错误的,因为它只会将返回类型更改为指向void的指针.你必须使用括号:
void (*t[5])(void);
这实际上会奏效.t是一个包含5个指向函数的数组,这些函数返回void并且不带参数.
大!一系列指向阿拉斯的指针怎么样?这非常相似.元素类型显示在左侧,维度显示在右侧.同样,需要括号,否则数组将成为整数指针的多维数组:
int (*t[5])[3];
而已!一个包含3个int数组的5个指针数组.
我们刚刚学到的功能也是如此.让我们声明一个带有int的函数,该函数返回一个指向另一个函数的指针,该函数不带参数并返回void:
void (*f(int))(void);
我们需要再次使用括号,原因与上述相同.我们现在可以调用它,并再次调用返回的函数.
f(10)();
那这个呢?
f(10)(true)(3.4);
?换句话说,一个函数如何使用int返回一个指向函数的指针,使bool返回一个指向函数的指针,该函数采用double并返回void看起来像?答案是你只是嵌套它们:
void (*(*f(int))(bool))(double);
你可以无休止地这样做.实际上,您也可以像指向函数的指针一样返回指向数组的指针:
int (*(*f(int))(bool))[3];
这是一个函数,它返回一个指向函数的指针,该函数使bool返回一个指向3 int数组的指针
既然上面已经解释了如何从基本类型构建复杂类型,那么您可以将const
它们放在您现在知道它们所属位置的位置.考虑一下:
T c * c * c ... * c name;
这T
是我们最后指向的基本类型.c
const或不是const 的代表.例如
int const * const * name;
将声明name 指向一个指向常量int的常量指针的类型指针.你可以改变name
,但你不能改变*name
,这将是类型
int const * const
并且都不是**name
,哪种类型
int const
让我们将它应用于上面的函数指针:
void (* const t[5])(void);
这实际上会声明数组包含常量指针.因此在创建(并初始化)数组之后,指针是const,因为它const
出现在星之后.请注意,const
在这种情况下我们不能放在星之前,因为没有指向常量函数的指针.函数根本不能是const,因为没有意义.所以以下内容无效:
void (const * t[5])(void);
实际上,C++和C声明函数和数组的方式实际上有点令人困惑.你必须首先考虑它,但如果你理解它,你可以使用它编写非常紧凑的函数声明.
在这种情况下,做一个typedef
命名你的功能签名,这使它更简单:
typedef void MESSAGE_HANDLER(void);
有了它,它应该只是:
MESSAGE_HANDLER * const handlers[] = { function1, function2 };
使数组的实际内容保持不变.
编辑:删除指针部分typedef
,这真的是更好(生活和学习).
cdecl
说:
cdecl> explain void (* const foo[])(void) declare foo as array of const pointer to function (void) returning void
这是你需要的吗?