【问题标题】:What does a const pointer-to-pointer mean in C and in C++?在 C 和 C++ 中,const 指针对指针的含义是什么?
【发布时间】:2010-09-25 02:16:31
【问题描述】:

我知道从右到左阅读声明的经验法则,我很确定我知道发生了什么,直到一位同事告诉我:

const MyStructure** ppMyStruct;

表示“ppMyStruct 是指向(可变)MyStructure 的 const 指针的指针”(在 C++ 中)。

我原以为它的意思是“ppMyStruct 是指向 const MyStructure 的指针的指针”。 我在 C++ 规范中寻找答案,但显然我不是很擅长...

in 在 C++ 中是什么意思,在 C 中是什么意思?

【问题讨论】:

    标签: c++ c pointers constants


    【解决方案1】:

    你的同事错了。那是一个(非常量)指针,指向一个(非常量)指向 const MyStructure 的指针。在 C 和 C++ 中。

    【讨论】:

    • 这也是您有时会看到替代“拼写推荐:MyStructure const * *ppMyStruct; 然后您可以阅读从右到左:指向 const Mystructure 的指针的指针”的部分原因。
    • 谁读 RTL?肯定没有我的客户 :-) 我认为我们不需要 RTL 支持,是吗?
    • 这是一篇旧帖子,所以我的评论问题可能不会被回答:如何创建一个指向 const MyStructure 的 const 指针的 const 指针?
    • @tchronis,我还没有测试过(只有它可以编译),但尝试类似:MyStructure const * const * const ptrMyStr;
    【解决方案2】:

    在这种情况下,工具 cdecl(或 c++decl)会很有帮助:

         [flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct"
         declare ppMyStruct as pointer to pointer to const struct s
    

    【讨论】:

    • 非常有用。为什么这个工具不为人所知?
    • 你碰巧知道它是否适用于 windows 吗?
    • 它是开源的,而且它对操作系统没有任何特定要求。如果幸运的话,它应该可以用任何编译器编译,在最坏的情况下,你必须使用 gcc/cygwin 或 mingw 的东西。
    • @flolo 你是个英雄!我从来没有听说过那个工具!谢谢你的分享! +1
    • 在线版本cdecl.org 反过来也可以!输入英文,获取代码。
    【解决方案3】:

    你的解释是对的。这是另一种看待它的方式:

    const MyStructure *      *ppMyStruct;        // ptr --> ptr --> const MyStructure
          MyStructure *const *ppMyStruct;        // ptr --> const ptr --> MyStructure
          MyStructure *      *const ppMyStruct;  // const ptr --> ptr --> MyStructure
    

    这些都是带有一个 const 限定符的指针的所有替代方案。从右到左的规则可用于破译声明(至少在 C++ 中;我不是 C 专家)。

    【讨论】:

    • MyStructure const* *ppMyStruct; 怎么样?
    • @tobi,这与第一行相同。请参阅stackoverflow.com/q/3694630(他们谈论引用,但指针的行为相同)。
    【解决方案4】:

    你的同事错了,C和C++也是一样。请尝试以下操作:

    typedef struct foo_t {
        int i;
    } foo_t;
    
    int main()
    {
        foo_t f = {123};
        const foo_t *p = &f;
        const foo_t **pp = &p;
        printf("f.i = %d\n", (*pp)->i);
        (*pp)->i = 888; // error
        p->i = 999;     // error
    }
    

    Visual C++ 2008 在最后两行给出以下错误:

    error C2166: l-value specifies const object
    error C2166: l-value specifies const object
    

    GCC 4 说:

    error: assignment of read-only location '**pp'
    error: assignment of read-only location '*p'
    

    G++ 4 说:

    error: assignment of data-member 'foo_t::i' in read-only structure
    error: assignment of data-member 'foo_t::i' in read-only structure
    

    【讨论】:

    • 为什么会被否决?我只是觉得最好举一个具体的例子,而不是仅仅告诉他他是对的。
    • 猜它是 Visual C++ 的仇恨者,GNU C++ 爱好者 :-)
    【解决方案5】:

    是对的。

    Another answer 已经指向“Clockwise Spiral Rule”。我非常喜欢那个——不过有点精致。

    【讨论】:

      【解决方案6】:

      作为其他 cmets 的推论,不要将 'const' 放在首位。它确实属于类型之后。那会立即澄清含义,就像往常一样阅读RTL:

      MyStructure const** ppMyStruct;
      

      【讨论】:

      • 我看不出这如何使它更清晰,但我想这是一个习惯问题。如果 const 先出现,我发现它与 RTL 一样容易阅读,就像“指向 MyStructure 的指针的指针,它是 const”。
      • 当我尝试它时,我得到了这个 cdecl> explain struct MyStructure const** ppMyStruct;语法错误任何人都可以解释为什么这是一个正确的 C 形式声明
      【解决方案7】:
      void Foo( int       *       ptr,
                int const *       ptrToConst,
                int       * const constPtr,
                int const * const constPtrToConst )
      {
          *ptr = 0; // OK: modifies the pointee
          ptr  = 0; // OK: modifies the pointer
      
          *ptrToConst = 0; // Error! Cannot modify the pointee
          ptrToConst  = 0; // OK: modifies the pointer
      
          *constPtr = 0; // OK: modifies the pointee
          constPtr  = 0; // Error! Cannot modify the pointer
      
          *constPtrToConst = 0; // Error! Cannot modify the pointee
          constPtrToConst  = 0; // Error! Cannot modify the pointer
      }
      

      【讨论】:

      • 我不明白这是对这个问题的回答。你看错了吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-24
      • 2011-03-11
      相关资源
      最近更新 更多