42

私は宣言を右から左に読むという経験則を知っており、同僚が私に次のように言うまで、何が起こっているのかを知っていたと確信していました。

const MyStructure** ppMyStruct;

「ppMyStruct は、(変更可能な) MyStructure への const ポインターへのポインター」 (C++ の場合) を意味します。

「ppMyStruct は、const MyStructure へのポインターへのポインターです」という意味だと思いました。C++仕様で答えを探しましたが、どうやら私はそれが得意ではありません...

C++ では in とはどういう意味ですか? C でも同じことを意味しますか?

4

7 に答える 7

66

あなたの同僚は間違っています。これは、const MyStructureへの(non-const)ポインターへの(non-const)ポインターです。CとC++の両方で。

于 2008-12-03T09:30:48.433 に答える
64

このような場合、ツールcdecl(またはc ++ decl)が役立ちます。

     [flolo@titan ~]$ cdecl explain "const struct s** ppMyStruct"
     declare ppMyStruct as pointer to pointer to const struct s
于 2008-12-03T09:44:52.353 に答える
23

あなたの解釈は正しかった。それを見る別の方法は次のとおりです。

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

これらはすべて、1 つの const 修飾子を持つポインターからポインターへの代替手段です。宣言を解読するには、右から左への規則を使用できます (少なくとも C++ では、私は C の専門家ではありません)。

于 2008-12-03T09:55:01.660 に答える
7

あなたの同僚は間違っています、そしてそれは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では、最後の2行に次のエラーが表示されます。

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
于 2008-12-03T09:45:45.067 に答える
5

あなたは正しいです。

別の答えはすでに「時計回りのスパイラルルール」を指しています。私はそれがとても好きでした - しかし、少し手の込んだものです。

于 2008-12-03T10:47:50.713 に答える
3

他のコメントの結果として、「const」を最初に置かないでください。それは本当にタイプの後に属します。それはすぐに意味を明確にするでしょう。いつものようにRTLを読んでください:

MyStructure const** ppMyStruct;
于 2008-12-03T13:52:34.990 に答える
0
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
}
于 2010-02-06T04:42:27.423 に答える