我需要像这样声明一个指向函数的指针数组:
extern void function1(void);
extern void function2(void);
...
void (*MESSAGE_HANDLERS[])(void) = {
function1,
function2,
...
};但是,我希望数组声明为常量--既包括数组中的数据,也包括指向数据的指针。不幸的是,我不记得把const关键字放在哪里了。
我假设实际的指针,在本例中是MESSAGE_HANDLERS,已经是常量了,因为它被声明为数组。另一方面,如果数组中的函数指针被声明为如下所示,那么在运行时不能更改它吗?
发布于 2008-12-03 16:26:53
有一种技术可以记住如何构建这样的类型。首先,尝试从指针的名称开始读取,然后从右向左读取。
如何在没有帮助的情况下声明这些东西?
数组
T t[5];是一个由5个T组成的数组。要使T成为函数类型,您可以将返回类型写在左边,将参数写在右边:
void t[5](void);是一个由5个函数组成的数组,返回,不带参数。但是函数本身不能填充在数组中!它们不是对象。只有指向它们的指针才能。
关于
void * t[5](void);这仍然是错误的,因为它只是将返回类型更改为void的指针。您必须使用括号:
void (*t[5])(void);这将会真正起作用。T是一个由5个指针组成的数组,指向返回void且不带参数的函数。
太棒了!那么指向arras的指针数组呢?这是非常相似的。元素类型显示在左侧,尺寸显示在右侧。同样,需要使用括号,因为否则数组将变成整数指针的多维数组:
int (*t[5])[3];就这样!一个由5个指针组成的数组,指向3个整型数组。
那么函数呢?
我们刚刚学到的关于函数的知识也是正确的。让我们声明一个函数,它接受一个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];这是一个采用int的函数,返回指向一个采用bool的函数的指针,返回一个指向3个int的数组的指针
这和const有什么关系?
既然上面解释了如何从基本类型构建复杂类型,您可以将const放在您现在知道它们所属位置的地方。试想一下:
T c * c * c ... * c name;T是我们最后指向的基本类型。c代表const或not 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方法实际上有点令人困惑。你必须先理解它,但是如果你理解了它,你就可以用它来编写非常紧凑的函数声明。
发布于 2008-12-03 15:23:01
在这样的情况下,做一个typedef来命名你的函数签名,这使得它变得简单得多:
typedef void MESSAGE_HANDLER(void);有了这一点,它应该是:
MESSAGE_HANDLER * const handlers[] = { function1, function2 };来获取数组常量的实际内容。
编辑:从typedef中删除了指针部分,这真的更好(在线学习)。
发布于 2008-12-03 15:25:11
cdecl说:
cdecl> explain void (* const foo[])(void)
declare foo as array of const pointer to function (void) returning void这是你需要的吗?
https://stackoverflow.com/questions/337449
复制相似问题