私のarduinoマイクロコントローラボードをC言語でプログラミングすると、私は奇妙な動作に気付きました。配列[-1]は配列の最後の要素を返しますか?
私のプログラムのロジックミスのため、コントローラは整数配列の-1
番目の要素にアクセスしました。
int array[5];
array[4] = 27;
// array[-1] gives 27 now.
それは私が要素セレクタとして-1
を使用して配列の最後の要素を取得していることが正しいですか?
私のarduinoマイクロコントローラボードをC言語でプログラミングすると、私は奇妙な動作に気付きました。配列[-1]は配列の最後の要素を返しますか?
私のプログラムのロジックミスのため、コントローラは整数配列の-1
番目の要素にアクセスしました。
int array[5];
array[4] = 27;
// array[-1] gives 27 now.
それは私が要素セレクタとして-1
を使用して配列の最後の要素を取得していることが正しいですか?
いいえ、インデックス範囲外の要素へのアクセスは、未定義の動作です。あなたのケースでは、あなたの配列の始めの直前のアドレスの要素は27に設定されています。
Cの配列要素にアクセスすることは、まっすぐなポインタ演算を行うことに過ぎないので、負のインデックスを渡すことは許されません。インデックスが負で正である正当なユースケースを構築することができます。
int raw[21], *data = &raw[10];
for (int i = -10 ; i <= 10 ; i++) {
data[i] = i;
}
プログラムを実行しましたが、クラッシュしませんでした。私は算術演算が行われていることを理解しています。驚くべきことに、gccコンパイラはエラーとしてエラーを出すことも警告を与えません。なぜそれが分かっていますか? –
いいえ。 array[-1]
は最後の要素にアクセスしません。配列の直前のメモリ位置に27
が格納されている可能性が高くなります。これを試してください:
array[4] = 27;
array[-1] = 0;
array[-1] == array[4]
のいずれかをテストします。彼らは平等ではありません(array[-1]
に割り当てるときにあなたのプログラムがクラッシュしないと仮定します)。
いいえ、それは標準に従って正しくありません。配列の外側の要素にアクセスすると、未定義の動作が呼び出されます。
あなたの実装は(その疑いはありますが)その機能を提供するかもしれません。しかし、あなたは本当にではなく、がそれに依存しています。
インデックスの範囲外の配列にアクセスしても、プログラムがクラッシュするとは限りません。 -1によってアクセスされたメモリがプログラムコントロールの下にある場合、未定義の値が飛び出します(プログラムによって作成された他のデータによって格納されます)。あなたの場合は単なる偶然です。
Cを指している場合(そしてあなたがいている場合)、いいえ。負のインデックスを持つ配列にアクセスしようとすると、範囲外の例外が発生します。しかし、Luaはこの正確なことを機能として実装しています。インデックスが-1のLua配列にアクセスすると、配列の最後の要素が読み込まれます。インデックスが-2の場合は、最後から2番目の要素が読み込まれます。
サイドノート:あなたはこれは迷惑な1を出力し、この
foo = {1,2,3,4,5,6,7,8,9,0}
print(foo.length() * -1])
を書き込むことによって、あなたの同僚を困らせることができ、そうではありません。
同じ論理エラーのため、最初にその場所に*書き込んだり、それからあなたが期待していたものを読むことができますか? – Irfy
@Irfy私はあなたの考えを知っていますが、そうではありません。 – danijar