私が言うなら、
int a[] = {1, 2, 3, 4, 5};
int *p = a;
今、私が書くp + 1 + 2
と、それは同じ((p + 1) + 2)
ですか?これが間違っていることを証明する標準的な参考文献はありますか?
私が言うなら、
int a[] = {1, 2, 3, 4, 5};
int *p = a;
今、私が書くp + 1 + 2
と、それは同じ((p + 1) + 2)
ですか?これが間違っていることを証明する標準的な参考文献はありますか?
範囲外に出ない場合のみ。たとえば、次のようになります。
int a[] = {1, 2, 3, 4, 5};
int *p = (a + 10) - 9;
int *q = a + (10 - 9);
への割り当てp
は未定義の動作を呼び出しますが、への割り当てはそうでq
はありません。
ただし、範囲内にいる限り、連想性が保持されることが期待できます。
ちなみに、あなたの質問では、あなたが与える2つのことは定義上同じであることに注意してください。つまり、x + y + z == (x + y) + z
ではありませんx + (y + z)
。
§3.7.4.3
2
A pointer value is a safely-derived pointer to a dynamic object only if it has pointer-to-object type and it is one of the following: ... the result of well-defined pointer arithmetic (5.7) using a safely-derived pointer value;
§5.7
3
The result of the binary + operator is the sum of the operands.
私には合法的に聞こえます。
ポインタと整数の間の加算は、C ++ 11で次のように定義されています(5.7 / 5)。
式Pが配列オブジェクトのi番目の要素を指している場合、式(P)+ N(同等にN +(P))および(P)-N(Nの値はn)は、それぞれ、配列オブジェクトのi+n番目およびi− n番目の要素(存在する場合)。
次の文は、配列の終わりを1つ過ぎたポインターについて説明しています。
したがって、ポインタを含む加算は、インデックスを含む加算と「同じもの」であり、もちろん連想的です。このことから、配列要素が存在する(または最後から1つ過ぎている)場合、ポインターを含む加算は結合的であると推測できます。
算術演算がポインターが指す配列の境界を超える場合、動作は未定義であるため、特に結合法則である必要はありません。
実際にはイエスだと思いますが、理論的にはノーかもしれません。
p + 3
と同じかどうかを尋ねて((p + 1) + 2)
いますが、標準では、ポインター演算は配列内またはその末尾の 1 つの要素のみで意味があるとされています。
ポインターは実際には単なる数字なので、はい、あなたが説明している方法で加算が連想されます。
編集: 以下の delnan のコメントを参照してください。はい、加算は連想されますが、ポインターは単なる数値であるという私の声明はまったく正しくありません。