• ベストアンサー

C言語の配列番号が"0"から始まる理由

C言語の配列番号は"0"から始まりますが "1"からではなく"0"から始める理由を教えてください。 例えば char a[5]; と宣言した場合 配列a[]は a[1], a[2], ・・・, a[5] ではなく、 a[0], a[1], ・・・, a[4] である理由を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
noname#88772
noname#88772
回答No.2

こんにちは。  a[] 配列が0から始まるのはその中身が配列スタートからの距離だからです。 a[0]は配列a[]のスタート地点です。 a[1]はa[]のスタート地点から1つ分離れた場所の値ということになります。  おそらくポインタをこれから習うと思いますが、 *p = a とした場合は *(p+1) の値は a[1] の値と同じになります。 本来の意味合いは異なりますが。  ご参考までに。

2nd_stage
質問者

お礼

なるほど。 ポインタのことは頭にありませんでした。 簡潔なご回答ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (7)

  • pick52
  • ベストアンサー率35% (166/466)
回答No.8

なんというか、簡単に云えばコンピュータにとっては0から始まって いる方が自然で分かりやすいわけです。 プログラミング言語はマシン語を少々人間に分かりやすくした アセンブリ言語を更に人間に分かりやすくするために作られたもの ですが、結局はコンピュータ本位なのでコンピュータに合わせなければ いけません。 何故、0から始まるのはというのを考えようとしても難しい話に なってしまいますので、単にそういうものだと覚えちゃった方が 簡単でしょう。 確かにプログラミング言語によっては添字が1から始まるものも ありますが、それはそういう仕様で作成しているだけです。 ただ、歴史的には0から始まるものだったので基本としてそのような 仕様のものが多いです。 また、途中から変更してしまうと混乱も招きます。

全文を見る
すると、全ての回答が全文表示されます。
  • yphkz4063
  • ベストアンサー率23% (34/144)
回答No.7

それは、C言語がアセンブリ言語だからです。

全文を見る
すると、全ての回答が全文表示されます。
  • don_go
  • ベストアンサー率31% (336/1059)
回答No.6

>C言語の配列番号は"0"から始まりますが 他の言語だと、VisualBasic(Basic), Java, C#等も0から 始まりますが、FORTRAN, COBOL等の様に1から始まる物も あります。 件名:配列の添字が0から始まるメリットは? http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=19588&forum=3&start=0

全文を見る
すると、全ての回答が全文表示されます。
  • snowize
  • ベストアンサー率27% (68/245)
回答No.5

細かいことは既に皆さんお答えになってくださっていますが、「添え字は番号ではなくオフセットである」とはよく言いますよね。 逆に言えば「どうして1番目から始めなければならないの?」とも考えられます。1番目から数えた方が分かりやすい……というのも主観に過ぎませんよ。

2nd_stage
質問者

お礼

> 1番目から数えた方が分かりやすい・・・というのみ主観にすぎませんよ。 確かにそうかもしれませんね。 ご指摘ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.4

CPUがどう配列を処理しているかの観点で考えるといいですよ。 int a[5]; と定義します。 a の アドレスが 0x1000 だったとします。 つまり、 a の1番目のアドレスは 0x1000 a の2番目のアドレスは 0x1001 ~~~~~~略~~~~~~~ a の5番目のアドレスは 0x1004 となります。 CPU は a[x] と指定された時、 0x1000 + x の位置として計算しますので、 1番目をさすには x は 0 である必要があります。 他の言語は...知りませんw 添え字をデクリメントしてるんでしょうかねぇ?

全文を見る
すると、全ての回答が全文表示されます。
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.3

ポインタと配列を同じ取り扱いにしているからです。 char a[5]; char *p = a; とあるときに、 配列へのアクセス a[i] と、 ポインタへのアクセス *(p+i) は、まったく同じ意味になります。 (それどころか、配列に対して *(a+i) というアクセスもできるし、 ポインタに対して p[i] というアクセスも可能。) C言語においては、配列アクセスのa[i] という表記方法は、 *(a+i) を、より分かりやすく記述するためのおまけ(シンタックスシュガー)なのです。 (だから、トリッキーですが i[a] という表記もアリです。i[a] は *(i+a) を意味しますから、*(a+i) である a[i] とまったく同じ意味になります。) このようなアクセス方法では、配列の要素へのアクセスは、 「先頭からいくつずらした要素にアクセスするのか」を意味します。 ですので、先頭の要素は、一つもずらしていない所の要素ということで、 配列の添え字は0から始まるのです。 添え字が1の場合は、1つずらした要素=先頭から2番目の要素、ということになります。

全文を見る
すると、全ての回答が全文表示されます。
noname#96023
noname#96023
回答No.1

符号なし整数の2進数が0から始まっているからじゃないですかね。 1から始めると、0.5ビット分損しますから 00000000→0 00000001→1

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語の型と配列

    char* str[10]={"a","b"}; char* str2="c"; としたときにstr=str2とすると 型が合わないといったエラーが出ます。 でもstrって結局はポインタの配列の先頭要素のアドレスですよね。 ポインタにポインタを入れているので通るのかなと思ったんですけど、 配列で宣言するとポインタにも型がつくのでしょうか? この例だと strは char * を10個持つ配列をさすポインタ  で、 str2はchar *をさすポインタ みたいなかんじです。 質問の意味がわかりにくいですが、ご指摘をいただければ補足しますので よろしくお願いします。

  • 配列の書き方

    C言語の配列の宣言で unsigned char aaa[256/8] という表現があるのですが、これはどういう意味でしょうか?

  • C言語Char型配列に小数値を入れる方法

    C言語Char型配列に小数値を入れる方法について質問なんですが、 分からなく質問させていただきました。 (例)23.8を float f = 23.8 char c[100]; cの配列の中に23.8を入れる c[0] = '2' c[1] = '3' c[2] = '.' c[4] = '8' c[5] = '\0' 上記みたいに入ってほしいんですが、そういうC言語の関数ありますか? itoaやsprintfを使わないでお願いします。

  • c言語の配列の境界調整について

    c言語の配列の境界調整について 以前、タイトル(c言語の境界調整について)の回答内容中で「データ型のアライメントとは何か、なぜ必要か」の下記のURLを紹介された中の配列の部分を 教えて頂きたい。 5.2 複合データ型の各要素のオフセット記述している、  (char * )&D == (char *)&D + offsetof(D_t, Di) は、配列にも適用されるのです か たとえば、 char s[4] = {1.2.3,4}; の場合    char * が 4バイトであれば、先頭のアドレスは、4バイトアライメントで    次の配列の要素は、1バイトアライメントでよろしいでしょうか   (http://www5d.biglobe.ne.jp/~noocyte/Programming/Alignment.html)

  • 配列変数のアドレス

    C言語で、配列を宣言した場合、 char a[] = "hoge"; 変数aは初期化された配列の先頭番地を指しているのですが、この時、 変数aの中身も変数aのアドレス(&a)ともに上記の配列の先頭番地になっているようなのですが、 これによって、配列の変数aは読み取り専用で、書き換えられないということにしていると思っていいのでしょうか? ちなみに、 char *p = "fuga"; とした場合は、pと&pのアドレスは異なって、pの中身は書き換えられます。

  • C言語 行列 配列

    現在、C言語を勉強中です。 C言語で (10000*10000)の大きさの行列を扱いたいです。 double a[10000][10000]の配列ではメモリ不足となってしまいます。 このような場合はどのようにプログラムを組んでいったら良いのでしょうか?

  • c言語の配列の先頭アドレスが偶数アドレスとなる理由について

    c言語の配列の先頭アドレスが偶数アドレスとなる理由について 下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。 /*list0105*/ #include <stdio.h> main() { char na=1; char nb=1; char c[2] ={1,2}; char s[3] = {1,2,3}; char nc=1; char nd=1; printf("%p\n",&na); printf("%p\n",&nb); printf("%p %p \n", &c[0],&c[1] ); printf("%p %p %p \n", &s[0],&s[1] ,&s[2] ); printf("%p\n",&nc); printf("%p\n",&nd); } 実行結果 0xbffff8cf 0xbffff8ce 0xbffff8cc 0xbffff8cd ← c配列 0xbffff8b0 0xbffff8b1 0xbffff8b2 ← S配列 0xbffff8af 0xbffff8ae

  • c言語 int型の数字をchar型の配列に

    c言語についてです。 int型の数字をchar型の配列に入れたいです。 関数に対してint型の数字を文字列として渡し、 関数内でchar型の配列に格納したいです。 例として、 a(char a[]){  ~~  ~~ } int main(void){ int x = 5678;  ~~  a(x); } とできるようにしたいです。 しかしこれだと5678という値がそのままchar型の一つの配列に入る?ため正しくないです。 欲しい結果としてはちゃんとa関数内で、 a[1] = '5' a[2] = '6' a[3] = '7' a[4] = '8' となってほしいです。 もともと渡す値が”5678”となっていれば結果は正しく出るのですが、 渡す値がint型と決まっているためどうにかして5678を”5678”とすればいいのではないかと考えています。 つまり5678を単純に文字列に変換すればいいのでしょうか? またプログラム内ではsprintfやatolを使用しないで実現させたいです。 難しいかもしれませんがお願いします。 なんだか説明が下手ですみません。 お願いいたします。

  • C言語の基礎的な質問---文字配列の初期化

    C言語の配列の初期化に関する質問です。 もし規格によって回答が異なる場合は、ANSIのCということにしてください。 関数の中に、 char str[ ]="ABC"; (イ) という宣言があるとします。(staticは付きません。) これは、 char str[ ]={'A', 'B', 'C', '\0'}; (ロ) と全く同じ意味でしょうか。  似て非なるものに char *str="ABC"; (ハ) というものがあります。この場合は、 strとは違うところに"ABC"('C'の次には'\0'があります。)という領域が確保されていて、 その先頭アドレスでstrが初期化されるのですよね。 (イ)(ロ)(ハ)のいずれの場合も関数の中に書かれているとすれば、 いずれもstrは自動変数で、関数実行時にstrの領域が確保されますよね。 (イ)は配列strの領域が確保されるときに、 配列strとは別のところにある"ABC"という領域の内容を、コピーして設定する、 ということでしょうか。 (ロ)は、配列の領域確保時にstr[0]を'A'で、str[1]を'B'で、str[2]を'C'で、str[3]を'\0'で、初期化する、 ということで、 配列とは別のところには"ABC"という領域はない、 という考えでよろしいでしょうか。 もしそうだとしたら、配列とは別のところに"ABC"という領域があるかどうかという点で(イ)と(ロ)は異なることになりますが、そう考えてよろしいのでしょうか。 それとも、そういうことは処理系に依存することなんでしょうか。

  • C言語で巨大配列を作るにはどうすれば良いのでしょうか?

    C言語で巨大配列を作るにはどうすれば良いのでしょうか? テストで作ってみた配列を用いたプログラムが動かなかったので(コンパイルは正常)、なんでだろうと思って調べてみると、巨大な配列はcalloc関数等を用いて作る必要があると知りました。 しかし正直解説サイトを見てもよく意味が分かりませんでした…。 例えばA[1000][1000][1000]の様な配列は、どの様に作ればいいのでしょうか? A[x][y][z]みたいに表現して、Aを変えて同じ様な配列を8個ほど作りたいです。 初心者なので勉強不足かも知れませんが、どうぞ宜しくお願い致します。