配列は、「0始まり」と「1始まり」、どちらが理想? – プログラミング – Home

配列は、「0始まり」と「1始まり」、ど...
 
通知
すべてクリア

[解決済] 配列は、「0始まり」と「1始まり」、どちらが理想?


まに
 まに
(@まに)
ゲスト
結合: 18年前
投稿: 78
Topic starter  

現在、VC++2005で、ちょっと大規模なプログラムを作成しています。
そこで、今、ちょっと悩みがあるのですが、

配列でデータを持たせる時の添え字は、
「0始まり」にするのと、「1始まり」にするのと、
一般的にどちらがよいのでしょうか?

一般的には、「0始まり」だと思います。
自分も、今までそうしてプログラミングしてきました。
しかし、今、作っているプログラムでは、
どうしても「1始まり」でデータを持たせなくてはならない配列が2つあって、
「だったら他の配列も『1始まり』に統一しようかどうしようか」と、悩んでいます。

以下に、自分なりにそれぞれのメリットを、挙げてみます。

● 「0始まり」のメリット

メリットA1
0始まりの方が、C言語っぽい。
(今までずっとそうしてきたので、慣れ親しんでいる。
0始まりの方が、なんとなくスマート)

メリットA2
0番目の添え字のデータが、無駄にならない。
(0番目の添え字が無駄になるのは、なんとなく気持ち悪い)

● 「1始まり」のメリット

メリットB1
外部仕様では、「1始まり」の数値をユーザーに見せることが多いので、
外部仕様のNoと、内部仕様のID(添え字)とを、そのまま対応できる。

メリットB2
数値の「0」を、「無効なID」を意味する数値として、利用できる。
(「無効なID」が「0」の方が、if文での比較も楽だし、初期化も楽)

メリットB3
添え字の0番目のデータを、何かの管理領域として使える。
(逆に、使えなければ無駄になる)

メリットB4
「ID(添え字)にマイナス符号を付けた数値」を、
「反ID」を意味する数値として利用できる。
(例えば「-5」という数値を、「5番目のデータが特別な状態である」
という意味を表す数値として使うことができる)

「1始まり」にしなくてはならない2つのデータは、
一つはメリットB3、もう一つは、メリットB2,B4の理由で、
どうしても「1始まり」の方が都合がいいんです。
しかし、「0始まり」と「1始まり」が混在するのも、
後になって混乱のもとになるかな、と思いまして…。

なので、
「基本は0始まりだけど、やむをえない場合は1始まりにする」
「いっそのこと、すべての配列を、1始まりに統一する」
の、どちらかで悩んでいます。

今のところ前者で考えてますが、
今後の方向性を決めることになるので慎重に決めたいと思い、
書きこませていただきました。
ご意見いただければ、幸いです。


引用未解決
トピックタグ
金魚ちゃん
 金魚ちゃん
(@金魚ちゃん)
ゲスト
結合: 16年前
投稿: 52
 

>「0始まり」にするのと、「1始まり」にするのと、
>一般的にどちらがよいのでしょうか?
C言語なら普通に0始まりが良いね。
VBじゃねぇし。

そうしないとC言語(C++)知っている人からすると
ソースを読むのが(概念の違いより)大変になるから。

>どうしても「1始まり」でデータを持たせなくてはならない配列が2つあって、
>「だったら他の配列も『1始まり』に統一しようかどうしようか」と、悩んでいます。
このデータだけ『1始まり』でいいのでは。

>メリットB1
>外部仕様では、「1始まり」の数値をユーザーに見せることが多いので、
>外部仕様のNoと、内部仕様のID(添え字)とを、そのまま対応できる。
外部とのやり取りで相互変換すればいいじゃん。
それだけでしょ。

>メリットB3
>添え字の0番目のデータを、何かの管理領域として使える。
こんな所に管理データを置くのは個人的に嫌い。
でも文字列を管理するときに

typedef struct myStr_t {
unsigned short len;
unsigned char str[1];
} myStr_t;
として文字列の先頭を str として取り扱うことはある。
この str より 2 バイト前にポインタを移動して文字列長を
取り出すとかに利用するかも。

>ご意見いただければ、幸いです。
配列ではなくて構造体で管理すればいいと思う。
あとは自由にどうぞ。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

1-originに見せかける小さなwrapper書けばいいじゃない。
ただの「決めごと」でしょ?


返信引用
悠
 悠
(@悠)
ゲスト
結合: 17年前
投稿: 40
 

UIのみ1始まりで表示させ、内部では0始まりで良いのでは?

#これは普通にされている事だと思うのですが。。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> 「いっそのこと、すべての配列を、1始まりに統一する」

char buf[1 + 1024 + 1];
strcpy(buf + 1, サンプル文字列);
buf[0] = strlen(サンプル文字列);
printf(%s\n, buf + 1);

こんなことする気はないんでしょ?
「すべての配列を、1始まりに統一」というのは
同じように無意味なことだと思う。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

おつかれ様です。つぼにはまってますね(笑)。
C/C++を始めた頃に似たようなことに悩みました。
結果、次のような意見を持つようになりました。

> メリットB1
> 外部仕様では、「1始まり」の数値をユーザーに見せることが多いので、
> 外部仕様のNoと、内部仕様のID(添え字)とを、そのまま対応できる。

「配列の添え字」と「UI上での表現上の番号」とは関係の無い2つの概念です。
いっしょくたにしてはいけません。つまりB1は誤った設計です。

> メリットB2
> 数値の「0」を、「無効なID」を意味する数値として、利用できる。
>(「無効なID」が「0」の方が、if文での比較も楽だし、初期化も楽)

カレントインデックスが無効であることを意味させる場合
「-1」とすることもできますし、「MAX+1」とする
考え方もあります。従ってB2の根拠は希薄です。

> メリットB3
> 添え字の0番目のデータを、何かの管理領域として使える。

配列を継承したクラスにすれば好きなだけ管理パラメータを追加できます。
わざわざ0番を使う意味はありませんし、型によっては使えません。
したがってB3のメリットはありえませんし、誤った設計です。

> メリットB4
> 「ID(添え字)にマイナス符号を付けた数値」を、
> 「反ID」を意味する数値として利用できる。
> (例えば「-5」という数値を、「5番目のデータが特別な状態である」
> という意味を表す数値として使うことができる)

B3と同じ理由で却下できます。特別な状態が1種類であるという
根拠の無い想定に基づいて設計されています。

従ってまにさんが上げている「1始まりのメリット」とやらは
全て却下できます。0始まりで実装するのが
正しい方法です。


返信引用
subaru
 subaru
(@subaru)
ゲスト
結合: 19年前
投稿: 381
 

>「1始まり」にしなくてはならない2つのデータは、
>一つはメリットB3、もう一つは、メリットB2,B4の理由で、
>どうしても「1始まり」の方が都合がいいんです。
>しかし、「0始まり」と「1始まり」が混在するのも、
>後になって混乱のもとになるかな、と思いまして…。

いっそ配列の添え字=IDという考え方をやめて普通に
CMapやstd::mapでキーとデータの組み合わせで管理してはどうでしょう。
メリットB3なんかは別途考慮が必要ですが
無効なIDとかはもともとデータとして存在してなくてもよさそうですし。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

うーーん、
僕もN88BASICからC言語学んだ方なんで分からなくもないですが、C言語の流儀でいった
ほうが分かりやすくなると思います。

> メリットB1
 VB主流でVCはDLLのみというならば分からなくもないですが、こんど、VCでそのDLLを
使おうとすると非常に使いづらくなる。

> メリットB2
> メリットB3
変数(BOOL等)を使ったほうがいいですね。

> メリットB4
これも、メリットB2,B3同様に変数(BOOL等)を使ったほうがいいですね。

仲澤さんもおっしゃっているようにクラスを利用すればもっとスマートにできますね。
僕の場合、構造体で済ませます。
そうすれば、B2~4までいっぺんに済みますね。


返信引用
まに
 まに
(@まに)
ゲスト
結合: 18年前
投稿: 78
Topic starter  

皆さん、ご意見ありがとうございました。
やっぱり1始まりって、自分が思ってた以上に、特殊なんですね。
おかげで決心が固まりました。
一時は、本気で、「1始まりに統一しようか」と、悩んでいたので…

皆さんのご意見を読んで、「1始まり」にした2つの配列も
見直した方がいいように思えてきました。
(でも、それで作っちゃってるしな…どうしよ…)

今後は、「基本0始まり」で行こうと思います。
どうもありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました