ary[-1]の動作

ary[-1]の動作

配列の-1番目の要素を指定した場合何が起こるのかちょっと興味あったので調べてみた

Pythonの場合

我らがPythonは後ろから1番目の意味になる。

ary = [1,2,3]
print(ary[-1]) # 3

Rubyの場合

RubyPythonと同じ仕様

ary = [1,2,3]
puts ary[-1] # 3

ところで

ary = 1..3
puts ary[-1] # 1..0

になるのは何故でしょうかね。Ruby良く分かりません…

Cの場合

未定義動作ですね

#include <stdio.h>
int main(void)
{
    int* ary[] = {1,2,3};
    printf("%d\n", ary[-1]); // 4195648
    return 0;
}

C++Vectorの場合

やはり未定義動作のようです。ちなみにC++11。

#include <iostream>
#include <vector>
int main()
{
    std::vector<int> v = {1, 2, 3};
    std::cout << v[-1] << std::endl; // 0
    return 0;
}

Javaの場合

例外が飛んできますね。

import java.util.Arrays;
import java.util.List;

public class Main {
	public static void main(final String[] args) {
		int[] ary1 = { 1, 2, 3 };
		List<Integer> ary2 = Arrays.asList(1, 2, 3);
		System.out.println(ary1[-1]); // java.lang.ArrayIndexOutOfBoundsException
		System.out.println(ary2.get(-1)); // java.lang.ArrayIndexOutOfBoundsException
	}
}

Groovyの場合

残念なJavaに脅威の魔科学を投入することで恐しいことになっているGroovyは、PythonRubyと同じ挙動

def ary1 = [1,2,3]
def ary2 = Arrays.asList(1,2,3)
println ary1[-1] // 3
println ary2[-1] // 3

Haskellの場合

Exceptionが飛んでくる模様

Prelude> let ary = [1,2,3]
Prelude> ary !! (-1) -- Exception: Prelude.(!!): negative index

D言語の場合

Range violationだそうで。

import std.stdio;
void main()
{
    int[] ary = [1,2,3];
    writeln(ary[-1]); // Range violation
}

結論

  • 古典的な言語は-1で範囲外参照する
  • スクリプト言語は一番後ろの値を持ってくる
  • 最近の静的型付け言語は例外を投げる