C++ 我们可以有多少级指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10087113/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:36:54  来源:igfitidea点击:

How many levels of pointers can we have?

c++cpointerslanguage-lawyerlimit

提问by Parag

How many pointers (*) are allowed in a single variable?

*单个变量中允许有多少个指针 ( )?

Let's consider the following example.

让我们考虑以下示例。

int a = 10;
int *p = &a;

Similarly we can have

同样我们可以有

int **q = &p;
int ***r = &q;

and so on.

等等。

For example,

例如,

int ****************zz;

回答by P.P

The Cstandard specifies the lower limit:

C标准规定了下限:

5.2.4.1 Translation limits

276 The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits: [...]

279 — 12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or void type in a declaration

5.2.4.1 平移限制

276 实施应能够翻译和执行至少一个程序,该程序包含以下每一项限制的至少一个实例:[...]

279 — 12 个指针、数组和函数声明符(任意组合)修改声明中的算术、结构、联合或 void 类型

The upper limit is implementation specific.

上限是特定于实现的。

回答by Kaz

Actually, C programs commonly make use of infinite pointer indirection. One or two static levels are common. Triple indirection is rare. But infinite is very common.

实际上,C 程序通常使用无限指针间接寻址。一两个静态级别是常见的。三重间接性很少见。但是无限是很常见的。

Infinite pointer indirection is achieved with the help of a struct, of course, not with a direct declarator, which would be impossible. And a struct is needed so that you can include other data in this structure at the different levels where this can terminate.

无限指针间接是在结构的帮助下实现的,当然,不是直接声明符,这是不可能的。并且需要一个结构,以便您可以在此结构中可以终止的不同级别包含其他数据。

struct list { struct list *next; ... };

now you can have list->next->next->next->...->next. This is really just multiple pointer indirections: *(*(..(*(*(*list).next).next).next...).next).next. And the .nextis basically a noop when it's the first member of the structure, so we can imagine this as ***..***ptr.

现在你可以拥有list->next->next->next->...->next. 这实际上只是多个指针间接引用:*(*(..(*(*(*list).next).next).next...).next).next. 而且.next基本上是一个空操作时,它的结构的第一个成员,所以我们可以想像这是***..***ptr

There is really no limit on this because the links can be traversed with a loop rather than a giant expression like this, and moreover, the structure can easily be made circular.

这真的没有限制,因为链接可以用循环而不是像这样的巨型表达式来遍历,而且结构可以很容易地制成循环。

Thus, in other words, linked lists may be the ultimate example of adding another level of indirection to solve a problem, since you're doing it dynamically with every push operation. :)

因此,换句话说,链表可能是添加另一个间接级别来解决问题的最终示例,因为您在每次推送操作时都动态地执行此操作。:)

回答by Alok Save

Theoretically:

理论上:

You can have as many levels of indirections as you want.

您可以根据需要拥有任意多的间接级别。

Practically:

几乎:

Of course, nothing that consumes memory can be indefinite, there will be limitations due to resources available on the host environment. So practically there is a maximum limit to what an implementation can support and the implementation shall document it appropriately. So in all such artifacts, the standard does not specify the maximum limit, but it does specify the lower limits.

当然,任何消耗内存的东西都不是无限期的,由于主机环境上可用的资源会存在限制。因此,实际上对于实现可以支持的内容存在最大限制,并且实现应适当地记录它。因此,在所有此类工件中,标准并未指定最大限制,但确实指定了下限。

Here's the reference:

这是参考:

C99 Standard 5.2.4.1 Translation limits:

C99 标准 5.2.4.1 翻译限制:

— 12 pointer, array, and function declarators (in any combinations) modifying an arithmetic, structure, union, or void type in a declaration.

— 12 个指针、数组和函数声明符(任意组合)修改声明中的算术、结构、联合或 void 类型。

This specifies the lower limit that every implementation mustsupport. Note that in a footenote the standard further says:

这指定了每个实现必须支持的下限。请注意,在脚注中,标准进一步说明:

18) Implementations should avoid imposing fixed translation limits whenever possible.

18) 实现应尽可能避免强加固定的翻译限制。

回答by BoBTFish

As people have said, no limit "in theory". However, out of interest I ran this with g++ 4.1.2, and it worked with size up to 20,000. Compile was pretty slow though, so I didn't try higher. So I'd guess g++ doesn't impose any limit either. (Try setting size = 10and looking in ptr.cpp if it's not immediately obvious.)

正如人们所说,“理论上”没有限制。然而,出于兴趣,我用 g++ 4.1.2 运行了它,它的大小可达 20,000。不过编译速度很慢,所以我没有尝试更高。所以我猜 g++ 也没有施加任何限制。(size = 10如果不是很明显,请尝试设置并查看 ptr.cpp。)

g++ create.cpp -o create ; ./create > ptr.cpp ; g++ ptr.cpp -o ptr ; ./ptr

g++ create.cpp -o create ; ./create > ptr.cpp ; g++ ptr.cpp -o ptr ; ./ptr

create.cpp

创建.cpp

#include <iostream>

int main()
{
    const int size = 200;
    std::cout << "#include <iostream>\n\n";
    std::cout << "int main()\n{\n";
    std::cout << "    int i0 = " << size << ";";
    for (int i = 1; i < size; ++i)
    {
        std::cout << "    int ";
        for (int j = 0; j < i; ++j) std::cout << "*";
        std::cout << " i" << i << " = &i" << i-1 << ";\n";
    }
    std::cout << "    std::cout << ";
    for (int i = 1; i < size; ++i) std::cout << "*";
    std::cout << "i" << size-1 << " << \"\n\";\n";
    std::cout << "    return 0;\n}\n";
    return 0;
}

回答by mihai

Sounds fun to check.

检查起来听起来很有趣。

  • Visual Studio 2010 (on Windows 7), you can have 1011 levels before getting this error:

    fatal error C1026: parser stack overflow, program too complex

  • gcc (Ubuntu), 100k+ *without a crash ! I guess the hardware is the limit here.

  • Visual Studio 2010(在 Windows 7 上),在出现此错误之前您可以有 1011 个级别:

    致命错误 C1026:解析器堆栈溢出,程序太复杂

  • gcc (Ubuntu),100k+*没有崩溃!我猜硬件是这里的限制。

(tested with just a variable declaration)

(仅使用变量声明进行测试)

回答by Nandkumar Tekale

There is no limit, check example here.

没有限制,请在此处查看示例。

The answer depends on what you mean by "levels of pointers." If you mean "How many levels of indirection can you have in a single declaration?" the answer is "At least 12."

答案取决于您所说的“指针级别”是什么意思。如果您的意思是“在一个声明中可以有多少个间接级别?” 答案是“至少 12 个”。

int i = 0;

int *ip01 = & i;

int **ip02 = & ip01;

int ***ip03 = & ip02;

int ****ip04 = & ip03;

int *****ip05 = & ip04;

int ******ip06 = & ip05;

int *******ip07 = & ip06;

int ********ip08 = & ip07;

int *********ip09 = & ip08;

int **********ip10 = & ip09;

int ***********ip11 = & ip10;

int ************ip12 = & ip11;

************ip12 = 1; /* i = 1 */

If you mean "How many levels of pointer can you use before the program gets hard to read," that's a matter of taste, but there is a limit. Having two levels of indirection (a pointer to a pointer to something) is common. Any more than that gets a bit harder to think about easily; don't do it unless the alternative would be worse.

如果您的意思是“在程序变得难以阅读之前您可以使用多少级别的指针”,那是一个品味问题,但有一个限制。有两个间接级别(一个指向某个对象的指针)是很常见的。再多一点就更难想了。不要这样做,除非替代方案会更糟。

If you mean "How many levels of pointer indirection can you have at runtime," there's no limit. This point is particularly important for circular lists, in which each node points to the next. Your program can follow the pointers forever.

如果您的意思是“在运行时您可以拥有多少级指针间接”,则没有限制。这一点对于循环列表尤其重要,其中每个节点都指向下一个。你的程序可以永远跟随指针。

回答by Matthieu M.

It's actually even funnier with pointer to functions.

使用指向函数的指针实际上更有趣。

#include <cstdio>

typedef void (*FuncType)();

static void Print() { std::printf("%s", "Hello, World!\n"); }

int main() {
  FuncType const ft = &Print;
  ft();
  (*ft)();
  (**ft)();
  /* ... */
}

As illustrated herethis gives:

如此处所示这给出了:

Hello, World!
Hello, World!
Hello, World!

你好,世界!
你好,世界!
你好,世界!

And it does not involve any runtime overhead, so you can probably stack them as much as you want... until your compiler chokes on the file.

而且它不涉及任何运行时开销,因此您可以随意堆叠它们……直到您的编译器阻塞文件为止。

回答by Sachin Mhetre

There is no limit. A pointer is a chunk of memory whose contents are an address.
As you said

没有限制。指针是一块内存,其内容是一个地址。
如你所说

int a = 10;
int *p = &a;

A pointer to a pointer is also a variable which contains an address of another pointer.

指向一个指针的指针也是一个包含另一个指针地址的变量。

int **q = &p;

Here qis pointer to pointer holding the address of pwhich is already holding the address of a.

q是指向保存地址的指针的指针,该指针p已经保存了 的地址a

There is nothing particularly special about a pointer to a pointer.
So there is no limit on chain of poniters which are holding the address of another pointer.
ie.

指向指针的指针没有什么特别的。
因此,持有另一个指针地址的指针链没有限制。
IE。

 int **************************************************************************z;

is allowed.

被允许。

回答by Mare Infinitus

Every C++ developer should have heard of the (in)famous Three star programmer

每个 C++ 开发人员都应该听说过(臭名昭著的)三星级程序员

And there really seems to be some magic "pointer barrier" that has to be camouflaged

似乎真的有一些神奇的“指针屏障”需要伪装

Quote from C2:

Three Star Programmer

A rating system for C-programmers. The more indirect your pointers are (i.e. the more "*" before your variables), the higher your reputation will be. No-star C-programmers are virtually non-existent, as virtually all non-trivial programs require use of pointers. Most are one-star programmers. In the old times (well, I'm young, so these look like old times to me at least), one would occasionally find a piece of code done by a three-star programmer and shiver with awe. Some people even claimed they'd seen three-star code with function pointers involved, on more than one level of indirection. Sounded as real as UFOs to me.

来自 C2 的引用:

三星级程序员

C 程序员的评级系统。您的指针越间接(即变量前的“*”越多),您的声誉就越高。非明星 C 程序员几乎不存在,因为几乎所有重要的程序都需要使用指针。大多数是一星程序员。在过去(嗯,我还年轻,所以至少对我来说这些看起来像过去),人们偶尔会看到由三星级程序员完成的一段代码,并敬畏地发抖。有些人甚至声称他们见过涉及函数指针的三星级代码,在不止一个间接层次上。对我来说听起来像不明飞行物一样真实。

回答by Kaz

Note that there are two possible questions here: how many levels of pointer indirection we can achieve in a C type, and how many levels of pointer indirection we can stuff into a single declarator.

请注意,这里有两个可能的问题:我们可以在 C 类型中实现多少级别的指针间接,以及我们可以将多少级别的指针间接填充到单个声明符中。

The C standard allows a maximum to be imposed on the former (and gives a minimum value for that). But that can be circumvented via multiple typedef declarations:

C 标准允许对前者施加最大值(并为此给出最小值)。但这可以通过多个 typedef 声明来规避:

typedef int *type0;
typedef type0 *type1;
typedef type1 *type2; /* etc */

So ultimately, this is an implementation issue connected to the idea of how big/complex can a C program be made before it is rejected, which is very compiler specific.

因此,归根结底,这是一个与 C 程序在被拒绝之前可以制作多大/复杂程度的想法相关的实现问题,这是非常特定于编译器的。