プロが教える店舗&オフィスのセキュリティ対策術

はじめまして。

C言語の初学者です。

sizeof(サイズオブ)演算子の理解でつまづいています。

参考書の説明は下記の通りです。



要素数を数えるのは面倒くさいので、要素数を自動的に求めて繰り返させることにします。
要素数を求める直接的な方法は用意されていませんが、計算することは出来ます。
配列全体のサイズを求め、それを要素1つのサイズで割れば要素の数がわかります。
C言語には、変数や配列のサイズを求めるsizeof(サイズオブ)演算子があります。
sizeof演算子は、次のようにして使います。
sizeof(変数や配列名)
sizeof演算子には()をつけなくても良いのですが、つけた方が読みやすいでしょう。
この演算子を使って配列arrayの要素数を求めるには次のようにします。
sizeof(array) / sizeof(array[0])



上記の説明文にある、【配列全体のサイズ】と【要素1つのサイズ】の【サイズ】とは何を指しているのでしょうか。

また、上記の【sizeof(array) / sizeof(array[0])】の割り算の意味が分かりません。

下記のプログラムを例にして、具体的に何を何で割っているのか数字を当てはめて教えてください。

よろしくお願い致します。



#include <stdio.h>

int main(void)
{
int array[] = {42,79,13,75,19};
int i;

for (i = 0;i < sizeof(array) / sizeof(array[0]);i++) {
printf("array[%d] = %d\n",i,array[i]);
}

return 0;
}

このプログラムの実行結果は次の通りになります。
array[0] = 42
array[1] = 79
array[2] = 13
array[3] = 75
array[4] = 19

A 回答 (5件)

サイズとはバイト数ですね。



intが4バイトの処理系だと、arrayは20バイト確保されます。すると、sizeof(array)は20、sizeof(array[0])はsizeof(int)と同じなので4です。sizeof(array)/sizeof(array[0])は20/4で5となり、配列の要素数と一致します。

この回答への補足

ご回答いただき、ありがとうございました。

【intが4バイトの処理系だと、arrayは20バイト確保されます。】と教えていただきましたが、arrayのサイズ20は、あらかじめ要素数が5と分かった上で、4バイト×要素数5=20バイトと計算しているのでしょうか。

もしそうなら、答えが5とわかっているのに、【sizeof(array)/sizeof(array[0])は20/4で5となり】というように後から割り算して要素数が5であると計算する意味がないのではと思いました(素人の素朴な疑問として)。

なぜ、【arrayは20バイト確保されます】となるのか詳しく教えてください。

よろしくお願い致します。

補足日時:2012/07/09 17:13
    • good
    • 0
この回答へのお礼

丁寧に教えていただき、ありがとうございました。

すっきりとしました。

お礼日時:2012/07/11 14:53

わざわざ組み込みの型と構造体型を区別する必然性が理解できません>#2.



「メモリを動的に確保する」場面であれば組み込み型だろうと構造体型だろうと sizeof のお世話にならざるを得ないし, あらかじめ配列の要素数の最大値が分かっているなら逆にどちらであっても sizeof など不要.

余談ですが, 個人的には配列であることがわかっているなら, その要素数は常に sizeof array/sizeof array[0] のようにとるべきだと思います. こう書けば, (array が配列として定義されている限り) 常に正しい値になりますし, ここを見ただけで「array の要素数」であることが明確ですからね.
    • good
    • 0
この回答へのお礼

ご回答いただき、ありがとうございました。

勉強になります。

お礼日時:2012/07/11 11:57

パソコンが要素の数を記憶する、即ち、プログラムを実行する度に自動的に要素の数が判定される、という訳ではありません。



このソースコードをコンパイルする、いくつかの処理の過程で、sizeof( … ) で記述された部分は、それに該当する変数の要素数を計算して、適当な値に差し替えられます。

for i = 0 to i < sizeof(…

という記述は、

for i = 0 to 5

になって、ここから実行型のプログラムが作られていきますので、プログラムを実行する段階では既に決まっているということになります。


明示的に、#define MAX 5
などとした時も、これを5から10とかに変更すると、ソースコード上、 for i = 0 to MAX と記述されている部分が、 for i = 0 to 10 と変更されてコンパイルされますが、sizeof を使ってもこれと同じことが行われます。



要は、define文 などで定義した 常数(Const) も sizeof() も コンパイル時に常数として処理されて、実行形式のプログラムになります。


ご参考に。
    • good
    • 0
この回答へのお礼

丁寧に教えていただき、ありがとうございました。

すっきりとしました。

お礼日時:2012/07/09 19:25

要素の数は、コンパイル時にすでに決まっているので、わざわざsizeof(array)/sizeof(array[0])という計算をする必要はありません。


しかし、この部分を固定値で5としていると、要素個数を増減する場合にarrayの初期化部分を直すのと同時に、for文の判断部分も直す必要があります。sizeofを使って計算させていれば、初期化部分を直すだけで、自動的に全要素に対してfor文がループしてくれます。
sizeofはコンパイル時に要素のサイズに置き換わるので、直接要素数を記述したのと出来上がるバイナリは同じになり、効率が下がるということもありません。
    • good
    • 0
この回答へのお礼

丁寧に教えていただき、ありがとうございました。

すっきりとしました。

お礼日時:2012/07/09 19:25

配列全体のサイズとは、 要素の数 × 要素のサイズ という意味になります。



要素のサイズは、バイト数と思ってよいです。なので、配列全体のサイズも全体のバイト数ということになります。


質問者殿のサンプルコードの例では、配列 array[] は、int型で、要素が、42、79,13,75,19の5個の配列ということになります。

一個の要素 即ち array[0] (要素は0番目でなくても良いですが) のサイズで、配列全体のサイズを割れば、要素の数が分かるということになります。

sizeof(array) / sizeof(arrya[0]) は、5ですね。

あとは、for 文 で、 i = 0 から i < 5 まで、各要素の内容を表示する、という構造になっています。



蛇足ですが、
int や、char の配列などでは、あまり積極的に使わなくても、配列の最大を先に定義してしまえば、sizeofなどを使わなくてもいいです。

#difein MAX 5
int array[ MAX ];
などの様に。この方が、後々コーディングし易いはずです。

sizeof が有効(というより有り難い存在)なのは、構造体や、構造体配列の時などでしょうね。恐らく、今後構造体などを学んで行くと、この有り難さが良く理解出来てくるかと思います。(定義した構造体配列のメモリ領域を確保する、など)

ご参考に。

この回答への補足

ご回答いただき、ありがとうございました。

【配列全体のサイズとは、 要素の数 × 要素のサイズ】と教えていただきましたが、パソコンが【int array[] = {42,79,13,75,19}】というプログラムの記述から要素の数を自動で5であると認識し、要素のサイズを掛けて配列全体のサイズを記憶しているのでしょうか。

教えていただきたく、お願い致します。

補足日時:2012/07/09 17:21
    • good
    • 0
この回答へのお礼

丁寧に教えていただき、ありがとうございました。

すっきりとしました。

お礼日時:2012/07/11 14:52

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!