当前位置: 首页 > 知识库问答 >
问题:

声明指向返回数组的函数的指针实际上合法吗?

谭池暝
2023-03-14

至少根据C11标准和我所读的内容。

返回类型不允许是数组类型的唯一地方是函数定义部分(在$6.9.1.3):

函数的返回类型应为 void 或数组类型以外的完整对象类型。

在函数调用($6.5.2.2.1)中,它声明:

表示被调用函数的表达式应具有指向返回 void 或返回数组类型以外的完整对象类型的函数的类型指针。

这意味着这样的事情是可以预期的:

int (*pf1)()[4]; //legal?

pf1(); //error calling a function which return array

我的意思是,根据我对标准的理解,只定义返回数组的函数是非法的,而没有定义返回数组的函数的指针。如果你能证明我是错的。同样,如果我错了,我会很高兴,如果你解释我,为什么这句话在标准呢?

虽然clang似乎不这么想,并且会在上面的代码中产生一个错误,声明“函数不能返回数组类型' int [4]”。但是这真的是一个函数吗(而不是一个指向函数的指针)?

编辑:

好的 - 我通过引用标准论文来回答“函数声明符”不能有返回类型的数组。但是,如果我们使用typedef名称来声明指向函数返回数组的指针 - 这是合法的吗?-

typedef int arr_t[4];

arr_t (*pf1)(void);

虽然我个人认为答案也涵盖了这种情况,因为“typedef”定义的类型名称与显式定义的类型名称相同。

共有2个答案

劳高爽
2023-03-14

声明函数返回数组的指针实际上是合法的吗?

不。这是不合法的。您将收到编译时错误。函数不能返回数组。

目前,如果整数 (*pf1)()[4]; 无论如何都有效,则函数调用

pf1(); 

没有任何意义pf1未指向任何函数。

都阳
2023-03-14

您找到的句子确实只是关于函数定义,而不是声明。但是,您忽略了另一个约束:

6.7.5.3函数声明符(包括原型)

约束条件

1函数声明符不应指定函数类型或数组类型的返回类型。

另外,如果我错了,我会很高兴,如果你解释一下为什么这个句子在标准中?

需要有一个额外的要求,即被调用的函数返回完整的对象类型,因为允许函数声明将其声明为返回不完整的类型:

struct S;
struct S f(); /* valid */
void g() { f(); } /* invalid */
struct S { int i; };
void h() { f(); } /* valid */

这与数组无关。关于“数组类型以外的”的措辞只是为了确保数组不会因措辞错误而意外被允许。

 类似资料:
  • 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个 指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是 函数指针。 函数指针的定义形式为: returnType (*pointerName)(param list); returnType

  • 主要内容:关于数组指针的谜题数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。以 为例,该数组在内存中的分布如下图所示: 定义数组时,要给出数组名和数组长度,数组名可以认为是一个 指针,它指向数组的第 0 个元素。 在C语言中,我们将第 0 个元素的地址称为数组的首地址。以上面的数组为例,下图是 arr 的指向:

  • 本文向大家介绍指针数组、数组指针、函数指针的区别?相关面试题,主要包含被问及指针数组、数组指针、函数指针的区别?时的应答技巧和注意事项,需要的朋友参考一下 指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。 数组指针:首先它是一个指针,它指向一个数组。在32

  • 问题内容: 我正在使用一个包含单个调用的.dll,该调用返回一个函数指针数组。GetMyApi()返回指向结构的指针,该结构是函数指针的数组。函数本身具有不同的单独输入和输出。到目前为止我尝试过的是: 我无法轻易更改的C代码: C中的代码: { int (__cdecl IsValidInt)(int i); int (__cdecl InvalidInt)(); int (__cdecl *Is

  • 6. 指向指针的指针与指针数组 指针可以指向基本类型,也可以指向复合类型,因此也可以指向另外一个指针变量,称为指向指针的指针。 int i; int *pi = &i; int **ppi = π 这样定义之后,表达式*ppi取pi的值,表达式**ppi取i的值。请读者自己画图理解i、pi、ppi这三个变量之间的关系。 很自然地,也可以定义指向“指向指针的指针”的指针,但是很少用到: int

  • C++ 数组 您可以先跳过本章,等了解了 C++ 指针的概念之后,再来学习本章的内容。 如果您对 C++ 指针的概念有所了解,那么就可以开始本章的学习。数组名是一个指向数组中第一个元素的常量指针。因此,在下面的声明中: double balance[50]; balance 是一个指向 &balance[0] 的指针,即数组 balance 的第一个元素的地址。因此,下面的程序片段把 p 赋值