web-dev-qa-db-ja.com

CおよびC ++のindex [array]による配列へのアクセス

一部のインタビュアーが何らかの理由で尋ねるのが好きなこの小さなトリックの質問があります:

_int arr[] = {1, 2, 3};
2[arr] = 5; // does this line compile?
assert(arr[2] == 5); // does this assertion fail?
_

私が理解できることから、_a[b]_は*(a + b)に変換され、加算は可換であるため、順序は重要ではありません。したがって、_2[a]_は実際には*(2 + a)です。それはうまくいきます。

これはCおよび/またはC++の仕様で動作することが保証されていますか?

38

はい。 6.5.2.1段落1(C99標準)では、[]演算子の引数について説明しています。

式の1つは「オブジェクトへのポインタtype」、もう1つの式は整数型、結果は「type」型になります。

6.5.2.1段落2(強調を追加):

後置式とそれに続く角括弧[]は、配列オブジェクトの要素の添え字付き指定です。 添え字演算子[]の定義は、E1[E2](*((E1)+(E2)))と同一であるということです。バイナリの+演算子に適用される変換規則のため、E1が配列オブジェクト(同等に、配列オブジェクトの最初の要素へのポインタ)であり、E2が整数の場合、E1[E2]は、E2E1番目の要素を指定します(ゼロから数えます)。

[]への引数の順序が正気である必要があることは何も述べていません。

36
Chris Lutz

一般に、_2[a]_は_a[2]_と同じであり、これはCとC++の両方で同等であることが保証されています(演算子のオーバーロードがないと仮定)。これは、意図したとおり、*(2+a)または*(a+2)、それぞれ。プラス演算子は可換であるため、2つの形式は同等です。

フォームは同等ですが、聖なるもの(および将来のメンテナンスプログラマー)のために、「a [2]」フォームを他のフォームよりも優先してください。

PS、面接でこれを求められた場合は、C/C++コミュニティに代わって正確な復讐を行い、必ず面接官にすべてのトリグラフシーケンスを与える前提条件としてリストするように依頼してくださいあなたの答え。おそらくこれは、将来、そのような(実際のプログラミング何かに関しては価値がない)質問をすることから彼/彼女を魅了するでしょう。インタビュアーが実際に9つのトリグラフシーケンスすべてを知っているという奇妙なイベントでは、仮想基本クラスの破棄順序についての質問で、いつでも別の試みを行うことができます。この質問は、日常のプログラミングとはまったく無関係です。

26