【问题标题】:What is the limit to the number of pointers to pointers we can have in C? [duplicate]我们在 C 中可以拥有的指向指针的指针数量的限制是多少? [复制]
【发布时间】:2020-06-24 07:57:42
【问题描述】:

在 C 语言中,我知道我们可以用指针来做到这一点:

int *p;          /* an int pointer (ptr to an int) */
int **pp;        /* a pointer to an int pointer (ptr to a ptr to an int) */

甚至:

int **app[];            /* an array of pointers to int pointers */
int (**ppa)[];          /* a pointer to a pointer to an array of ints */
int (**ppf)();          /* a pointer to a pointer to a function returning an int */
int *(*pap)[];          /* a pointer to an array of int pointers */
int **fpp();            /* a function returning a pointer to an int pointer */

但是我们可以做类似三个指向无限的事情吗?例如:

int ***ppp;             /* a pointer to a pointer to an int pointer */
int ****pppp;           /* a pointer to a pointer to a pointer to an int pointer */

...以此类推直到无穷大。

我们可以拥有的指向指针的指针数量是否有上限?如果有,上限是多少?

【问题讨论】:

  • 理论上没有限制。实际上,编译器可能有一个可能远高于所需的限制。此外,诸如int ***foo 之类的三个以上的间接寻址很少(如果不是从不)有用。另请阅读this
  • @RobertSsupportsMonicaCellio 很棒的建议……我会做的。
  • 这是一个有趣的问题,我点了它,但它一直是asked and answered already
  • @ryyker 是的,我也想知道我是否没有在其他任何地方看到它,但正忙着思考它,并且没有太多的灵感来寻找它,虽然我找到了它,但你更快; -)。

标签: c pointers language-lawyer limit


【解决方案1】:

该标准没有规定任何上限。它确实说的是编译器需要支持至少 12.

在实际代码中,它可以被认为是无限的。只有当您编写的程序编写了人类不应该阅读的程序时,这才是相关的。大多数程序员会说你应该拿三颗星作为警告。没有非常好的理由,不要超过两个。

我在 gcc 上尝试了 10000 并且它有效。我现在正在尝试 100000。一件有趣的事情是编译需要很长时间。编译花了几分钟,唯一的语句是一个带有 10000 颗星的指针声明。

生成C文件的代码:

// gen.c
#include <stdio.h>

int main()
{
    const size_t n = 10000;
    printf("int main(){int ");
    for(size_t i=0; i<n; i++)
        printf("*");
    printf("p;}\n");
}

运行:

$ gcc gen.c -c gen
$ ./gen > stars.c
$ gcc stars.c

对cmets的回答:

这是一个有趣的实验,但我不会进一步研究。

【讨论】:

  • hmmmm....有趣的笨蛋。看起来它还取决于正在使用的编译器......在这种情况下,我确信永远不会有编译器来处理无限的指针,或者也许所以如果有限制,限制是使用的编译器而不是能力使用无限数量的指针...对吗?
  • 是否可以完全解除对这个指针的引用或者这会导致未定义的行为?
  • @RobertSsupportsMonicaCellio 我想要做的不是使用一个指针来浏览一个非常大的文本文件,这对我来说似乎很慢,如果可能的话,我试图通过添加更多指针来提高速度。到目前为止,三个看起来不错......但我什至不确定使用三个是否是一个好习惯,更不用说添加更多......
  • @Danish 因为你可以在没有任何 UB 的情况下声明这么多指针,你也可以 use 并使用 dereference 它们,但你必须通过分配和访问指出的内容,仔细使用正确的排版。
  • “这是一个有趣的实验,但我不会进一步研究。” - +1
【解决方案2】:

C 11 标准没有规定最大限制,实际上规定“实施应尽可能避免施加固定的翻译限制。” in a footnote.

最小限制由5.2.4 Environmental limits给出:

实现至少应该能够翻译和执行 一个程序,其中至少包含一个实例 以下限制:18)

  • 127 个嵌套级别的块
  • 63 个嵌套级别的条件包含
  • 12 个指针、数组和函数声明符(以任意组合形式)修改 a 中的算术、结构、联合或 void 类型 声明
  • 在完整的声明器中嵌套 63 层括号内的声明器
  • 完整表达式中括号表达式的 63 个嵌套级别
  • 内部标识符或宏名称中的 63 个有效初始字符(每个通用字符名称或扩展源字符 被视为单个字符)
  • 外部标识符中的 31 个重要初始字符(每个通用字符名称指定一个短标识符 0000FFFF 或 less 被认为是 6 个字符,每个通用字符名称 指定 00010000 或更多的短标识符被认为是 10 字符,并且每个扩展源字符都被认为是相同的 字符数作为相应的通用字符名称,如果 任何)
  • 一个翻译单元中有 4095 个外部标识符
  • 511 个标识符,在一个块中声明了块范围
  • 4095 个宏标识符同时定义在一个预处理翻译单元中
  • 一个函数定义中有 127 个参数
  • 一个函数调用中有 127 个参数
  • 一个宏定义127个参数
  • 一个宏调用中有 127 个参数
  • 逻辑源代码行中有 4095 个字符
  • 字符串文字中的 4095 个字符(连接后)
  • 对象中的 65535 个字节(仅在托管环境中)
  • #included 文件的 15 个嵌套级别
  • switch 语句的 1023 个 case 标签(不包括任何嵌套 switch 语句的标签)
  • 单个结构或联合中的 1023 个成员
  • 单个枚举中有1023个枚举常量
  • 单个 struct-declaration-list 中的 63 级嵌套结构或联合定义

符合标准的 C 编译器将提供至少 12 级指针间接。

【讨论】:

    猜你喜欢
    • 2021-01-26
    • 1970-01-01
    • 2015-02-16
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多