int a[2][3];
cout << a+1 << " " << a << " " << (a+1) - a << endl;
出力:出力を理解するには?
0029FAC0 0029FAB4 1
は(a+1)-a
は0029FAC0-0029FAB4=12
ではないでしょうか?
int a[2][3];
cout << a+1 << " " << a << " " << (a+1) - a << endl;
出力:出力を理解するには?
0029FAC0 0029FAB4 1
は(a+1)-a
は0029FAC0-0029FAB4=12
ではないでしょうか?
いいえ、指していることに応じて、ポインタの算術演算はになります()。この場合、合計4バイトの整数の3要素配列を指しており、合計12バイトです。しかし、それはあなたの算術の1つの「要素」に縮小されています。
それは(それがスケーリングないだとき0029FAB4 + 1
)a+1
をプリントアウトするときに0029FAC0
ではなく0029FAB5
を取得するのと同じ理由です。
あなたがあなたの出力ラインを変更した場合:
cout << a+1 << " "
<< a << " "
<< (a+1) - a << " "
<< (int)(a+1)-(int)(a) << endl;
あなたはそれがもはやポインタの減算なのでスケーリングは、最終的な用語では消えません表示されます:
0xbfaa0ad4 0xbfaa0ac8 1 12
ことに留意してくださいの(int)(a+1)
はa
が依然としてポインタであるため、まだ縮尺されています。です。この時点では、両方の値が整数に変換されています(通常の警告はポインタと整数間の変換に適用されるため、私の特定の実装では安全ですが、C99ではそれを強制しません)。
ええ、なぜ '(a + 1) - a'は' 12'ではないのですか? – lex
@lex、申し訳ありません、私はそれを明確にしたいと思っていました - それは12bytes_ですが、それは1_element_に縮小されています。 – paxdiablo
優秀な説明。よくやった。 +1(縮尺) – wilhelmtell
cout << b << b - a << endl;
ただ(pointerA - pointerB)
と他の道を進んでポインタ引数後のN番目のデータ要素に(pointer + N)
ポイントとしてあなたにポインタbetweeenデータ要素の数を示します。この場合、データ要素はint[3]
です(これは、あなたが12を期待していることから明らかです)。
生のアドレス値(一般的にはマシンに依存します)の違いは期待できません。 C/C++は変換しています。
ポインタ演算は、まだ有効な算術;-)
で、有効な算術演算のように、それは(x+1)-x = x - x + 1 = 1
と考えています。
だからあなたの場合には(a+1)
はない配列の2番目の要素へのポインタが、配列終了後のバイトへポインタを意味します。
ポインタをプリントアウトすると、基本的に暗黙的に、バイトアドレスを使用して表示用の整数にキャストされます。
ポインタを減算すると、結果はptrdiff_t
になります。これはすでに整数型です。同じタイプのポインタのみを減算することができ、sizeof
タイプが計算に含まれます。結果は、バイト数ではなく、2つのポインタ間の要素数です。 (2つのポインタが同じ配列を指していない場合、減算は未定義の振る舞いです。)
あなたの場合、ポインタの型は「3 intsの配列へのポインタ」であり、2つのポインタはそのうちの2つの配列の2つの隣接する要素(3 intの配列)に渡します。それらは1要素離れていますが、12バイト離れています。
'*(a + 1) - * a'は' 3'を返し、 'int(a + 1) - int(a)'は '12'を返します。 –
'a + 1-a'は' 1'であるとは思わないでしょうか?それは論理的な答えのように、 'a'は1を離れてお互いをキャンセルします。 –