8

コメントのある行を参照してください:

  • 例に括弧を追加すると、配列のすべての内容が出力されるのはなぜですか?

この例では、「one」を出力してから、ゴミを出力します。

#include <iostream>

int main() {
    const char* a[3] = { "one", "two", "three" };
    const char*(*p)[3] = &a;
    for(int i = 0; i < 3; i++) {
        std::cout << *p[i] << std::endl; // this line
    }
    return 0;
}

これに変更した後に動作します:

std::cout << (*p)[i] << std::endl;
4

4 に答える 4

22

p次のような 3 つの要素の配列へのポインターです。

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
   ^
   └─ p

配列の単一の要素ではなく、配列全体を指していることに注意してください。

式は、演算子の優先順位 ( と同等) による*p[i]ものとして扱われます。これは、配列へのポインターにインデックスを付けていることを意味します。たとえば、ポインタを「次の」配列に移動し、逆参照を試みます。*(p[i])*(*(p + i))p[1]

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
                     ^
                     └─ p + 1

ご覧のとおり、そこには何もなく、未定義の動作が発生します。ただし、(*p)[i]( と同等*((*p) + i)) を実行すると、逆参照が最初に行われるようになります。逆参照により、配列自体が得られます。これは、配列からポインターへの変換によって、配列の最初の要素へのポインターに暗黙的に変換できます。だからあなたが得るものは次のとおりです:

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
   ^
   └─ *p

この場合、ポインタは配列全体ではなく配列要素を指しています。次に、たとえば にインデックスを付けると、次の(*p)[1]ようになります。

┌─────┬─────┬─────┐
│     │     │     │
└─────┴─────┴─────┘
         ^
         └─ (*p) + 1

これにより有効なconst char*値が得られ、それを で出力できますcout

于 2013-04-15T11:03:23.630 に答える
6

演算子の優先順位。なしの()演算子[]が最初に呼び出され、その結果は になりますdereferenced。With ()-firstly になりdereference、次に operator を呼び出します[]

于 2013-04-15T11:00:15.810 に答える
3

演算子の優先順位

配列の選択は逆参照よりも優先度が高いため、コンパイラの観点からは次のようになります。

*(p[i])
于 2013-04-15T11:00:15.353 に答える