在C/C++中如何声明返回指向int值数组的指针的函数指针?

7

这个正确吗?

int (*(*ptr)())[];

我知道这可能是琐碎的,但我在看一份关于这些结构的旧测试时,这个特定的组合没有出现在测试中,这真的让我疯了;我必须确保。对于这些声明,有明确而可靠的理解规则吗?(例如:指向...数组的指针...指向...函数的指针等等)

谢谢!

R


4
谢谢赞赏!我会尽力将标题翻译得更通俗易懂。原意是表扬标题让人印象深刻,但同时也让人感到困惑,再加上标题名字引起了一些笑声。 - Russell
可能可以把这个作为答案,但要记住顺时针螺旋规则,它可以双向工作,只需根据方向进行调整。 - jer
boost::function<int*[] ()> 是你能接受的东西吗? - Gustavo Muenz
6个回答

17

右左规则使其易于理解。

int (*(*ptr)())[];可以被解释为:

从变量名开始---------------------------ptr

向右没有任何内容,但有 ),因此向左走以找到 * -------------- 是一个指针

跳出括号并遇到 () ----------- 指向一个不带参数的函数(在C语言中未指定参数数量)

向左走,在那里找到 * ------------------------------------------------ 并返回指针

跳出括号,向右走并命中 [] ---------- 指向一个数组

再次向左走,在那里找到 int ------------------------------------- 整数


5
这个并不容易。我喜欢使用typedef来把它分解一下。 - Mark Ransom
请注意,这个例子不是一个有效的声明 - 要使其成为有效声明,需要指定数组大小。 - caf
2
@caf:这会使类型成为不完整的类型,但您仍然可以在声明中使用指向不完整类型的指针。 - CB Bailey
1
@Charles Bailey:原来如此!我从不知道指向不完整数组类型的指针是可用的类型,但事实就是如此。正如人们所说,你确实每天都会学到新东西。 - caf

5
在几乎所有需要返回数组指针的情况下,最简单的方法是返回指向数组第一个元素的指针。这个指针可以在与数组名相同的上下文中使用,并且与返回“指向数组的指针”类型的指针没有更多或更少的间接性,实际上它将持有相同的指针值。
如果您遵循这个规则,您需要一个返回指向int类型指针的函数指针。您可以构建这个声明(声明的构建比解析容易)。
指向int类型的指针:
int *A;

返回指向 int 的指针的函数:

int *fn();

指向返回指针的函数,该指针指向 int

int *(*pfn)();

如果您真的想要返回一个指向返回一个指向 int 数组的函数的指针,可以按照相同的过程进行操作。
整型数组:
int A[];

指向整数数组的指针:

int (*p)[];

函数返回指针...:

int (*fn())[];

指向函数的指针…:

int (*(*pfn)())[];

你所拥有的就是这个。


2
你不需要这样做。只需将其拆分为两个typedef:一个用于指向int数组的指针,另一个用于指向函数的指针。类似于以下内容:
``` typedef int* IntArrayPtr; typedef void (*FunctionPtr)(); ```
typedef int (*IntArrayPtr_t)[];
typedef IntArrayPtr_t (*GetIntArrayFuncPtr_t)(void);

这不仅更易读,而且使得声明/定义要赋值给变量的函数更容易:

IntArrayPtr_t GetColumnSums(void)
{ .... }

当然,这假设这是一个真实的情况,而不是一个面试问题或作业。对于那些情况,我仍然认为这是更好的解决方案,但这只是我的个人意见。 :)

1
如果你觉得想作弊:
typedef int(*PtrToArray)[5];
PtrToArray function();

int i = function;

在gcc上编译会产生以下错误:invalid conversion from 'int (*(*)())[5]' to 'int'。第一部分是您正在寻找的类型。

当然,一旦您拥有了PtrToArray类型定义,整个练习变得更加琐碎,但有时如果您已经知道函数名并且只需要将其放在某个地方,则这非常有用。出于某种原因,您无法依赖模板计数来隐藏详细信息时,这也很有用。

如果您的编译器支持,您也可以执行以下操作:

typedef int(*PtrToArray)[5];
PtrToArray function();

template<typename T> void print(T) {
    cout << __PRETTY_FUNCTION__ << endl;
}

print(function);

在我的电脑上,这会产生 void function(T) [with T = int (* (*)())[5]]

能够阅读类型是非常有用的,因为理解编译器错误通常取决于您能否弄清楚所有那些括号的含义。但是,在我看来,自己制造它们的用处不大。


0

这是我的解决方案...

int** (*func)();

返回一个int*数组的函数对象。它并不像你的解决方案那么复杂。


0

使用cdecl,您将得到以下内容

cdecl> declare a as pointer to function returning pointer to  array of int;
Warning: Unsupported in C -- 'Pointer to array of unspecified dimension'
    (maybe you mean "pointer to object")
int (*(*a)())[]

这个问题来自C-faq,与此类似,但提供了3种解决方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接