- ベストアンサー
先頭アドレスとは何ですか?
Cの勉強をするため、Cの勉強用のホームページを読んでいたのですが その中に 「“int a[10];”というふうに配列を宣言した場合、配列名“a”はその配列の先頭アドレスになります」 という一文がありました。これが理解できません。 「アドレス」はメモリ内の、変数が記憶されている場所のことですよね。 先頭アドレスの「先頭」とは一体何に対して「先頭」なのでしょうか。 「一番前」という意味でしょうか。なら何の中で一番前なのでしょう? さらにそのホームページでは 「配列名“a”を式の中に書くと、普通は配列の先頭要素を指すポインタになります」 と言いなおしていましたが、これもよくわかりません。 「先頭要素」とは? 一体何に対する先頭なのでしょう?要素の先頭とは何を指すのかがいまいちピンときません。 初心者にありがちなお恥ずかしい質問ではありますが、ご教授いただければ幸いです。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
例えば、int型が4バイトの場合... int a[10]; のように配列を宣言すると、 +0+1+2+3 a[0]: □□□□ a[1]: □□□□ a[2]: □□□□ a[3]: □□□□ a[4]: □□□□ a[5]: □□□□ a[6]: □□□□ a[7]: □□□□ a[8]: □□□□ a[9]: □□□□ (□1つが1バイトを表しています) のようにメモリ上には配置されます。 ここで、「先頭要素」というのは、配列aの最初の要素のことですからa[0]のことです。先頭アドレスというのは、先頭要素a[0]の最初のアドレス(上の表では+0のところのアドレス)になります。 各要素(a[0]とかa[1]とか)は、それぞれint型ですから4バイトで構成されます。この4つのバイトには、それぞれアドレスがふられているわけですが、具体的に整数値のどの部分がどのアドレスに相当するかは処理系(多くの場合はプロセッサ)に依存します。 例えば、馴染みの深いIntelのプロセッサの場合、通常、次のようになります。 a[0]が0x12345678という値だった場合、 +0: 0x78 +1: 0x56 +2: 0x34 +3: 0x12 のように格納されます。 なお、 > 「配列名“a”を式の中に書くと、普通は配列の先頭要素を指すポインタになります」 の意味するところは、配列型は多くの場合、暗黙的にポインタ型に型変換されます。ポインタ型に型変換された場合、元の配列の先頭要素を指すポインタの値になります。「普通は」とあるのは、そうならない場合もあるということです。具体的には、sizeof演算子や&演算子のオペランド(演算対象)になった場合です。
その他の回答 (5)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★0x と 12345678 の関係 ・int 型が 4 バイトのとき、a という配列1つに 0x12345678 という値(データ)を代入したとします。 するとメモリ上では下のようにセットされます。 a[ 0 ] = 0x12345678; 1バイト目が 0x78 の1バイトデータ 2バイト目が 0x56 の1バイトデータ 3バイト目が 0x34 の1バイトデータ 4バイト目が 0x12 の1バイトデータ となります。 ・なお、上記のメモリ・イメージは Intel 系のプロセッサ(CPU)の場合です。 もしも、Motorola 系のプロセッサ(CPU)の場合は 1バイト目が 0x12 の1バイトデータ 2バイト目が 0x34 の1バイトデータ 3バイト目が 0x56 の1バイトデータ 4バイト目が 0x78 の1バイトデータ となります。 ・通常のプログラミングでは、あまり意識しなくても良いですが、メモリ・イメージをファイルに 保存したり読み出したりするときは、プロセッサ(CPU)の違いにより上記のような2タイプがあるのです。 Intel 系のプロセッサ(CPU)のような格納方法を『リトルエンディアン』と呼び、 Motorola 系のプロセッサ(CPU)のような格納方法を『ビッグエンディアン』と呼びます。 また、格納方法のことを『バイトオーダー』とか、単に『エンディアン』などと呼びます。 ・『今までは 1001 とか、1002 などの単純な数字のアドレス…。』となっていますが、0x12345678 は アドレスの数値ではありません。データの内容(値)のことです。 jacta さんの回答にあった int 型(4バイト)に 0x12345678 の値を代入したときのメモリ・イメージが +0: 0x78 +1: 0x56 +2: 0x34 +3: 0x12 と格納されますよ。って事です。 1バイトずつ 0x78、0x56、0x34、0x12 と順番に格納されるのが『リトルエンディアン』方式で CPU は Intel のプロセッサとなります。→私の使っているパソコンは Intel 系ですので『リトルエンディアン』 方式でメモリにはデータが格納されているようです。68000系(Motorola) のパソコンならばバイト列が 逆転して格納され、この方法が『ビッグエンディアン』なのです。 ・以上。分かりましたか。 参考文献: ・http://www.atmarkit.co.jp/icd/root/70/5784470.html→『バイトオーダー』 ・http://cai.int-univ.com/sugsi/Lecture/NetProg/chapter3/byte_order.html→『バイトオーダについて』
お礼
穴だらけの理解で申し訳ありません。 しかし、こうしてご指導いただき、とても勉強になります。 ありがとうございます。 0x と 12345678 の関係につきましては、最初Motorola 系のプロセッサの考え方が先にきてしまい、 なぜ一バイト目に大きい方から埋めていくのかなあ・・・と考えておりました。 PCの環境もプログラミングに大きく影響するのですね・・・ 一応知識としては知っていたつもりでしたが、ここでもこんな違いが生まれるとは知りませんでした。 このたびはどうもありがとうございました。
- jacta
- ベストアンサー率26% (845/3158)
> 必ずしも先頭要素=先頭アドレスではないということはわかりました。 そうではなく、必ずしも配列名=先頭アドレスではないということです。 確かに、必ずしも先頭要素=先頭アドレスではないのですが、それはまた別の話です。
補足
基本的なところを間違えていましたね…お恥ずかしいです。 間違えたまま覚えるところでした。 ご指摘、どうもありがとうございました。
- asuncion
- ベストアンサー率33% (2127/6289)
> 0xと12345678の関係 0xは、16進数のことです。0~9, a~f(大文字も可)の16種類の文字を 使って数値を表現します。 0x12345678と書くと、「千二百三十四万五千六百七十八」ではなく、 1*(16の7乗)+2*(16の6乗)+3*(16の5乗)+...+7*(16の1乗)+8 を表わします。
- asuncion
- ベストアンサー率33% (2127/6289)
int a[10]; と配列を定義すると、メモリ中のどこかのアドレスに a[0]~a[9]の10個の要素を連続して配置します。 このとき、配列名aは、配列の先頭要素であるa[0]を 格納しているアドレスと同義です。
お礼
回答ありがとうございます。 物に例えるなら、 部屋の中に番号の書いたダンボール箱を0~9番の順に置いて、 番号の若い順から前→後ろと定義していく感じでしょうか。 0番の置いてある場所が畳の一枚目であれば、 一番目の畳が先頭アドレス(0~9番のダンボールの代表住所) になる・・・みたいな感じで頭に置き換えて考えています。 一応自分でも調べてみたのですが、「先頭アドレス」ではIT単語集にひっかからず困っておりました。 解説していただけてとても助かっています。
- suzukikun
- ベストアンサー率28% (372/1325)
>先頭アドレスの「先頭」とは一体何に対して「先頭」なのでしょうか。 a[10]としてメモリ上に取られる領域の「先頭」になります。 >「先頭要素」とは? この場合だとa[0]になります。配列の「先頭」です。構造体なども同じように表せるので「先頭要素」という言い方になります。
お礼
回答ありがとうございます。 ←使用 メモリ領域→ 0 1 2 3 4 5 6 7 8 9 前 ■■■■■■■■■■ 後ろ ↑ ↑ ここ a=10 こういう感じでよろしいのでしょうか? 何をもってして前とするのか後ろとするのかはよくわかっていないのですが・・・ 添え字の順番で一番小さいのが先頭・・・だと思います。 >構造体なども同じように表せるので「先頭要素」という言い方になります。 なるほど! 先頭アドレスと先頭要素の二種類の呼び方があるのはそういうことだったのですね。 このたびはどうもありがとうございました。
お礼
わかりやすい図での解説、ありがとうございます。 今までメモリ領域のことを棒グラフのように直線状だと思い込んでいましたが、 バイトの存在をすっかり忘れておりました。 ここで気づくことができてよかったです。 >a[0]が0x12345678という値だった場合 お礼欄に質問を書くのもどうかと思うのですが、 0xと12345678の関係がよくわかりません。(無知ですみません・・・) 今までは1001とか、1002などの単純な数字のアドレスしか見たことがなかったもので・・・ 簡単でいいので、ご説明願えませんでしょうか。 >「普通は」とあるのは、そうならない場合もあるということです。 >具体的には、sizeof演算子や&演算子のオペランド(演算対象)になった場合です。 sizeof演算子や&演算子のオペランド(演算対象)はまだ習っていないのでよくわかっていないのですが、 必ずしも先頭要素=先頭アドレスではないということはわかりました。 今後sizeof演算子等を勉強する際の参考にさせていただきます。 このたびはどうもありがとうございました。