Zsh配列の最初の要素が0ではなく1でインデックス付けされる理由はありますか?


27

最近のプログラミングおよびスクリプト言語の経験から、ほとんどのプログラマーは一般に、配列の最初の要素をインデックスとして0で参照することに慣れていると思います。1
を使用することで実質的な利点はありますか?

Zsh以外の言語でも、配列と同様に動作することを聞いたことがあると思います。それは同じように便利なので、私は大丈夫です。
ただし、以前にリリースされ、広く使用されているkshやbashなどのシェルスクリプト言語ではすべて0が使用されているため、 なぜこの共通の「標準」を変更することを選択するのでしょうか。

私の質問に対する私の即時の答えは「もちろんそうではない」でしょう。
シェルに対するこの「排他的な機能」に関して私が考えることができる唯一の説明は、「彼らはクールなシェルをもう少し見せるためにこれをやっただけ」だろう。

私はZshやその歴史についてあまり知りませんが、これに関する私の些細な理論が意味をなさない可能性が高いです。

これについての説明はありますか?それとも個人的な趣味から外れているのでしょうか?


5
0対1のトピックに関するいくつかの歴史的研究(または反すうを反論しますか?)exple.tive.org/blarg/2013/10/22/citation-needed
thrig

歴史的な理由からcsh、これはおそらく1 から始まる配列インデックスを使用したから来たものです。
クオンルム

3
現在、shはさまざまなインタープリターを持つ標準言語(実装ではなく)です。bash、ksh、yashなどのsh言語のインタープリターの一部は、拡張として配列をサポートしていますが、gccのような言語の一部ではありません。標準C言語のコンパイラは、標準C言語の拡張をサポートしています。Cと同様に、「sh」インタープリターの「公式」実装はありません。
ステファンシャゼル


4
少し話題から外れているかもしれませんが、関連性があります。ローマ人は、ゼロではなく1から始まる包括的カウントを使用していました。明日、「2日先」の私たちにとっては、「3日先」でした。彼らは今日、ゼロではなく1として数えた。その結果、エジプトの天文学者が4年ごとにうるう日を推奨したため、ローマ人は実際に3年ごとに紀元前45年からうるう日を導入しました。エラーを修正するには、紀元前12年までかかりました。
ハリーウェストン

回答:


32
  • 事実上すべてのシェルアレイ(Bourne、csh、tcsh、fish、rc、es、yash)は1から始まります。kshは私が知っている唯一の例外です(bashはkshをコピーしただけです)。
  • ほとんどの解釈時の言語(90年代初頭): awktcl少なくとも、およびツールは、一般的にシェルから使用(cut -f1-3head -n 3sort -k1,3cal 1 2015comm -1)1から始まりsededvi1から数彼らの行...
  • zshは、Bourneシェルとcshを最大限に活用します。Bourneシェル配列$@は1から始まります。zshは、$@(Bourneのように)または$argv(cshのように)の処理と一貫しています。たとえば、最初の定位置パラメーターが得られないksh場所で、それがどれほど混乱するかを確認してください${@:0:1}
  • シェルは、プログラミング言語になる前のユーザーツールです。ほとんどのユーザーにとって、に最初の要素があることは理にかなっています$a[1]。また、要素の数が最後のインデックスと同じであることも意味します(zshでは、kshを除く他のほとんどのシェルと同様に、配列はスパースではありません)。
  • a[1]最初の要素はa[-1]最後の要素と一致しています。

IMOの質問はむしろ、配列が0から始まるようにするためにDavid Kornの頭に何が入ったのでしょうか?


7
それは人間の言語のバグであり、番号付けは1ベースであり、ほとんどのプログラミング言語がそのレガシーを設計から守ることに成功した驚くべきセレンディピティです。すべての悲しい、ということの後にゼロベースのインデックスが事実上の標準として確立された、非常に多くの「ユーザー指向」言語は使用して、「単純」になろうと、後方それを得た間違って、再び、1ベースのインデックス。—とはいえ、インデックス付けの混乱を避ける最良の方法は、もちろん数値インデックスを完全に避けることです。

ここを読む:「下付き文字で区別したい要素の長さNのシーケンスを扱うとき、... a)下付き文字1で始まるとき、下付き文字の範囲1≤i <N + 1;ただし、0はより良い範囲0≤i <Nを提供します。TROLLまたはSTUPIDかどうかはわかりませんが、配列で1から始まる添え字に「1≤i≤N」を使用できます。配列スキャンの最後にその+1を置く必要はありません。また、どちらの観点からも、1または0で始まるインデックスの方が良いことを証明しません。

1
0が人間の知識の後に追加されたことを正当化することができます。theguardian.com/notesandqueries/query/0,5753,-1358,00.html-繰り返しますが、単に視点の問題です:)

3
Bourneシェル配列$ @は0(1ではない)で始まります。$ 0は実行中のプログラムの名前です。3番目のポイントを修正する必要があります
エドワードトーバルズ

2
@edwardtorvalds、いいえ、$0位置パラメータではありません。の一部ではありません$@"$@"です"$1" "$2" ...。それが機能になると、多くのシェルでは、あなたはそれを参照して"$@"、関数の引数であるが$0滞在スクリプトパス(またはシェルARGV [0]スクリプトを実行していない)
ステファンChazelas

7

これに対するもっともらしい答えは、 zsh

4つの要素を持つ配列がある場合はmyvar=(1 2 3 4)、4番目の要素にアクセスするとしますprint $myvar[4]

ただし、この配列内の要素を逆方向にリストするループを作成する場合は、負のインデックスを使用するだけです。

print $myvar[-1]   # will print 4
print $myvar[-2]   # will print 3
print $myvar[-3]   # will print 2
print $myvar[-4]   # will print 1

これは、ゼロから始まるため、説明がないはず-0です。これらの要素の1つには到達しないためです。

この背後にある2番目の理由は、おそらくzshの変数に関連するCコードが配列インデックスを使用intまたはdouble int定義するためであり、2の補数を使用して負の数を表すため、floatでできるように-0符号付きゼロ)を表す方法がありませんポイント変数。

0から始まるインデックスに本当に慣れている場合、KSH_ARRAYSこれを修正するオプションを使用することをお勧めします。

そして、@ cuonglmコメントのフックを取って、csh実装されてzshいる機能をここで説明します。それは歴史的な理由ではなく、と一緒に使用されている人に快適な作業環境を提供する方法のようですcsh


3
次に、これにより、最初と最後の配列項目に同時にアクセスできるようになり、配列をスキャンするすべてのロジックが破壊されます;)ブラックホールを作成することさえできます。LOL

3
インデックスが0の配列の場合は、-で置き換えます~
mikeserv

1
@mfxx-私は話していましたbashセット要素の負のインデックスを構文シュガーとして処理しますが、そうでない場合は処理しません。思い出せない。私の観点からは、人々はディレクトリを作成し、シェルの状態に詰め込むファイルを使用する必要があります。好きな方法でこれらの要素にインデックスを付けることができます。
mikeserv

1
~バイナリ反転です。~0です-1。(すべてのビットが反転され、負の数が通常ビット単位で表される方法に依存します)。未設定の配列、またはインデックス0の要素が1つだけの配列では、a [0]、a [-0]、a [-1]、a [〜0]はkshのような配列で同じことを行います。
ステファンシャゼル

1
@StéphaneChazelas-ええ、うまくいかなかった~ときにこれを処理したことを覚えていると思います-index。たぶん私がしたことはすべてだったと思い~-indexます。ええ。そうですね。はい!もちろん、設定されていない要素でも機能します。したがって、上記のコメントは-0インデックス付き配列addの はず~です。多分-1の部分を簡単に処理できたと思います。私は知らないよ。そのは...現時点では私の記憶の最前線へのジャンプではない
mikeserv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.