有一种技术可以记住如何构建这种类型。首先尝试从名称开始读取指针,并从右向左读取。
如何在没有帮助的情况下声明这些东西?
数组
T t[5];
是一个5 T 的数组。要使 T 成为函数类型,请将返回类型写在左边,将参数写在右边:
void t[5](void);
将是一个包含 5 个函数的数组,返回 void 并且不带任何参数。但是函数本身不能塞进数组中!它们不是对象。只有指向它们的指针可以。
关于什么
void * t[5](void);
这仍然是错误的,因为它只会将返回类型更改为指向 void 的指针。您必须使用括号:
void (*t[5])(void);
这实际上会起作用。t 是一个包含 5 个指针的数组,指向返回 void 且不带参数的函数。
伟大的!指向 arras 的指针数组呢?这非常相似。元素类型显示在左侧,尺寸显示在右侧。同样,需要括号,否则数组将成为整数指针的多维数组:
int (*t[5])[3];
就是这样!一个由 5 个指针组成的数组,指向 3 个 int 的数组。
函数呢?
我们刚刚学到的关于函数也是正确的。让我们声明一个带有 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];
这是一个函数,它返回一个指向函数的指针,返回一个指向 3 int 数组的指针
它与 const 有什么关系?
既然上面解释了如何从基本类型构建更复杂的类型,你可以把它们放在const
你现在知道它们所属的地方。只需考虑:
T c * c * c ... * c name;
TheT
是我们最后指向的基本类型。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
请注意,在这种情况下,我们不能在星号之前放置 a ,因为没有指向常量函数的指针。函数根本不能是 const ,因为那没有意义。因此以下内容无效:
void (const * t[5])(void);
结论
C++ 和 C 声明函数和数组的方式实际上有点令人困惑。您必须首先了解它,但如果您理解它,您可以使用它编写非常紧凑的函数声明。