配列のsizeofに関する疑問 - C言語

このQ&Aのポイント
  • C言語で配列のsizeofに関する疑問があります。
  • 関数内で配列のsizeofを使用すると正しく動作しないため、その理由を知りたいです。
  • 初心者の質問ですが、よろしくお願いします。
回答を見る
  • ベストアンサー

引数が配列のときの関数内でのsizeofについて

こんにちは. Cを勉強している最中に疑問にあったことを質問させていただきます.以下のプログラムで配列myarrayの中の最大のメンバーを見つけるプログラムです.コメントアウトしてある //int ary_size = sizeof(myarray)/4; をグローバル変数で定義するとうまく最大の数を見つけてくれるのですが, 関数の中で int ary_size = sizeof(ary)/4; と定義するとうまくいきません.そこで,以下の printf("The size of the ary is %d\n",ary_size); という表示を追加したところ,ary_size = 1となっていることが分かりました. なぜそうなるのでしょう?関数の引数はint ary[]の配列なので,sizeof(ary)でaryがメモリ中で占めるバイト数が得られるんじゃないんですかね?ちなみに私の環境ではsizeof(int)は4バイトなので int ary_size = sizeof(ary)/4; と割る4で配列のメンバーの数を求めています. 初心者の質問ですみませんがよろしくお願いします. #include <stdio.h> #include <Windows.h> int myarray[] = {1,2,3,4,5,6,7,2}; int FindMax(int ary[]); //int ary_size = sizeof(myarray)/4; int main() { int max; max = FindMax(myarray); printf("The maximum value is %d\n",max); Sleep(2000); return(0); } int FindMax(int ary[]) { int ary_size = sizeof(ary)/4; int i; int max; max = ary[0]; for(i=1;i<ary_size;i++) { if(ary[i]>max) { max = ary[i]; } } printf("The size of the ary is %d\n",ary_size); return(max); }

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

int FindMax(int ary[]) と宣言しても FindMaxに渡されるのは 配列aryの先頭要素のアドレスだけです 配列自体が関数に引き渡されるわけではありません 配列を扱う関数では 呼び出し側で 配列の先頭アドレスと要素数を渡すといった手法をとります int FindMax( int ary[], int nSize) {   int i;   int max;   max = ary[0];   for(i=1;i<nSize;i++)   {     if(ary[i]>max)     {       max = ary[i];     }   }   printf("The size of the ary is %d\n",ary_size);   return(max); } といった具合に定義します 呼び出し側で int myArray[] = {1,2,3,4,5,6,7,2}; // 配列全体の大きさを 配列の1つの要素の大きさで除算することで 要素数を算出する int nLen = sizeof(myArray) / sizeof(myArray[0]); max = FindMax(myArray, nLen); といった具合で …

nasanaut
質問者

お礼

ありがとうございます.便利な使い方も教えてもらえたので今後の参考になりました.

その他の回答 (1)

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.2

>int FindMax(int ary[]) >{ >int ary_size = sizeof(ary)/4; ary の宣言は、int ary[] で、これは int *ary と同じ意味です。 つまり、sizeof(ary) はポインタのサイズになります。 これは、Cでは配列自体を引数で渡せないことから来ています。配列の先頭アドレスのポインタを渡すことになる。

nasanaut
質問者

お礼

返信ありがとうございます.そういえば >配列の先頭アドレスのポインタを渡すことになる。 ことを学んだのに忘れていました.実際に出くわして,思い出しました.ありがとうございます.ポインタ変数の大きさを得ていたのですね!

関連するQ&A

  • 引数で指定された配列の要素数の取得

    どうもこんにちは。 C言語でプログラムを作成しています。 ある関数に配列を渡すことを考えていますが、渡した配列の要素数を取得する方法は何かありますか? 標準の関数を見ても、配列の先頭アドレスのポインタとともに、配列の要素数を渡しているものばかりで、配列のポインタを渡しているものは見かけません。 要素数があらかじめわかっていれば、それを引数の型に指定できますが、呼び出されるまで不明な場合はうまくいきません。 配列の要素数も引数として一緒に渡す必要がありますか? [作ってみたサンプル] #include <stdio.h> #include <stdlib.h> #include <string.h> // func1 と func2 をまとめられないだろうか。。。 void func1(int (*p)[10]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } void func2(int (*p)[5]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } int main(int argc, char *argv[]) { ________int ary1[10] = { 2, 4, 6, 8, 0, 1, 3, 5, 7, 9 }; ________int ary2[5] = { 3, 6, 9, 12, 15 }; ________func1(&ary1); ________func2(&ary2); ________return 0; }

  • 【C言語】関数へのポインタ渡し

    配列中の最大値を発見するプログラムとして, 下記のようなプロブラムが参考書にのっていましたが,よくわからない箇所があり,質問させてください。 findMaxという関数に渡されているのは,aryの先頭アドレスだと思いますが, findMax関数内では,pary[]を引数としていますが,これはどういう意味なのでしょうか? 実際にどのような処理が行われているのかよくわかりません。 ポインタ変数? でもそのあとにはpary[0],pary[1]として使っているしよくわかりません。 教えていただけると嬉しいです。宜しくお願いいたします。 最近Cを学び始めましたが,ポインタがまだなれません…。 ============================ #include <stdio.h> #define DATA_SIZE (12) int ary[] = {5,7,10,1,25,15,30,10,31,13,22,32}; int findMax(int *, int); int main(void) { int max; int i; max = findMax(ary,DATA_SIZE); printf("Maximum number is %d\n",max); return(0); } int findMax(int pary[],int size){     int max;       int i; max = pary[0]; for(i = 0; i < size; i++){ if(pary[i] > max){ max = pary[i]; } } return(max); }

  • sizeof

    main() { char array1[256] = "abcdefg"; char *array2 = "stuvwxyz"; printf("array1 = %d\n",sizeof(array1)); // array1 = 256 printf("array1 = %d\n",sizeof(array1)/sizeof(char)); // array1 = 256 printf("array2 = %d\n",sizeof(array2)); // array2 = 4 printf("array2 = %d\n",sizeof(array2)/sizeof(char *)); // array1 = 1 printf("array2 = %d\n",sizeof(*array2)); // array2 = 1 } となるのですが、sizeof(array1)では、配列のサイズが取得できるのですが、array2がさす配列のサイズを得るためにはどうすればいいのですが?もしくは取得デキナイのはなぜでしょうか。 それと、 sizeof(array2)では、charへのポインタをさすから4バイト。 sizeof(*array2)では、sizeof(array[0])を意味するから1バイト という解釈でいいでしょうか。

  • sizeof()の使い方

    あるプログラムでちょっと珍しいソースコードがありました。 *************************************************************** int x[7]; int nx = sizeof(x) / sizeof(x[0]); for (i = 1; i < nx; i++) { -省略- } *************************************************************** sizeof()という珍しい関数を使っています。 このプログラムの目的は、sizeof()を使って、forの繰り返し回数を算出して、 プログラマー側がアルゴリズムを考えて、forの繰り返し回数を設定する手間を省いてくれることにあります。 しかし、ちょっとおかしな事がありまして、 printf("sizeof(x)="); printf("%d\n",&sizeof(x)); printf("sizeof(x[0])="); printf("%d\n",&sizeof(x[0])); printf("nx=sizeof(x) / sizeof(x[0]):"); printf("%d\n",&nx); を使って、sizeof(x),sizeof(x[0]),nxに何が設定されたかを確かめたところ、 sizeof(x)=28 sizeof(x[0])=7 nx=1638196 と分かりました。nxは”7”でないとおかしいと思うのですが、いかがでしょうか?

  • ポインタのsizeofについて

    C初心者です。 ポインタ宣言させた変数をsizeof()で値を取得させて 表示させてみました。 char *cp; short int *sp; int *ip; i = sizeof(cp); printf("%d\n",i); i = sizeof(sp); printf("%d\n",i); i = sizeof(ip); printf("%d\n",i); 結果は全て4となりました。 これはなぜですか? (ただの変数として宣言すれば1、2、4となります。この理由も理解できています。)

  • 二次元配列による文字列の配列の受渡しについての質問です。

    二次元配列による文字列の配列の受渡しについての質問です。 #include <stdio.h> void print_pname(char str[][5], int n) { int i, j; for (i = 0; i < n; i++) { printf("str[%d] = \"", i); for (j = 0; str[i][j] != '\0'; j++) putchar(str[i][j]); printf("\"\n"); } } int main(void) { char ary[][5] = {"Lisp", "C", "Ada"}; print_pname(ary, sizeof(ary) / sizeof(ary[0])); return 0; } 上のプログラム中の関数print_pnameの引数char str[][5]についてですが char (*str)[5](配列のポインタ)と変更した場合にwarningが多数発生します。 これはどうしてでしょうか? また、上のプログラムを配列のポインタを使って変更することは可能でしょうか? 以上、よろしくお願いします。

  • C言語のsizeof(サイズオブ)演算子について

    はじめまして。 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

  • 配列へのファイルの入出力

    C言語の質問です。 下記のプログラムについてint size、int valueのそれぞれの配列の数値をプログラムに直接描くのではなく、 テキストファイル等にあらかじめ書いた数値をfget関数などを用いてファイルの一行目はint sizeに、二行目はint valueに数値として入力・・・といったような感じで使用出来るよう書き換えたいのですが、 どのようにプログラムを書き換えれば可能になるでしょうか?ご教授いただけると幸いです。 #include <stdio.h> #include <stdlib.h> /* 配列size、valueはそれぞれ品物の大きさと価値を表している。 同じ添え字同士が対応している。たとえば、品物0の大きさはsize[0]、 価値はvalue[0]に入っている */ /* 品物の大きさ */ int size[] = {2, 3, 5, 7, 9}; /* 品物の価値 */ int value[] = {2, 4, 7, 11, 14}; /* 品物の種類の数 */ #define N (sizeof(size)/sizeof(size[0])) /* ナップザックの大きさの上限 */ #define MAX_M 200 int main(int argc, char **argv) { int i, j; /* ナップザックの大きさ */ int m; /* 現時点でナップザックに詰め込んだ品物の価値の合計 */ int total[MAX_M]; /* 最後に選んだ品物 */ int choice[MAX_M]; /* 品物iを入れたときの価値の合計 */ int repack_total; if (argc != 2) { fprintf(stderr, "usage: knapsack m\n"); fprintf(stderr, " ここで、mはナップザックの大きさ\n"); exit(1); } /* コマンド引数からナップザックの大きさを得る */ m = atoi(argv[1]); printf("size of knapsack is %d\n", m); if (m >= MAX_M) { fprintf(stderr, "ナップザックの大きさが大きすぎます\n"); exit(1); } /* 配列をクリアしておく */ for (i = 0; i <= m; i++) { total[i] = 0; choice[i] = -1; } /* 品物0~iまでを考慮に入れる */ for (i = 0; i < N; i++) { /* 大きさjのナップザックに対して、品物を詰め込んでみる */ for (j = size[i]; j <= m; j++) { /* もし品物iを入れたとすると、価値の合計はいくらに なるかを計算して、変数repack_totalに入れる */ repack_total = total[j - size[i]] + value[i]; /* 品物iを入れたほうが(入れないより)価値が大きくなる のなら、品物iを入れる */ if (repack_total > total[j]) { total[j] = repack_total; choice[j] = i; } } /* 配列total、choiceの中身をダンプする */ printf("i = %d\n", i); printf("total = "); for (j = 0; j <= m; j++) printf("%2d ", total[j]); printf("\nchoice = "); for (j = 0; j <= m; j++) printf("%2d ", choice[j]); printf("\n"); } /* どの品物をナップザックに入れたかを表示する */ for (i = m; choice[i] >= 0; i -= size[choice[i]]) printf("品物 %d (価値%d)を詰め込む\n", choice[i], value[choice[i]]); printf("価値の合計 = %d\n", total[m]); return (0); }

  • 関数先にて配列の長さを取得する方法

    関数にて、引数にて渡された配列(ポインタ)から配列数を調べる方法はないでしょうか? #include <stdio.h> void test(unsigned int *p){ printf ("%d\n", sizeof(*p)/sizeof(p[0])); //結果 1 } int main(){ unsigned int hoge[] = {0x30, 0x31,0x32}; test(hoge); printf("%d", sizeof(hoge)/sizeof(hoge[0])); //結果3 return 1; } 上記コードの関数testの*pから配列の数3が抜き取りたいと思っております。 よろしくお願いします。

  • 配列の動的確保を関数化

    main()内でいくつかの配列を動的確保するとごちゃごちゃするので、 関数化してみました。しかし、下のプログラムではうまい事いきませ んでした。 #include<stdio.h> #include<stdlib.h> void array1d(int *box,int n) { int i; box=(int *)malloc(n * sizeof(int)); for(i=0; i<n; i++) { box[i]=0; } } main() { int *pol,i,n; printf("N pol\nN = "); scanf("%d",&n); array1d(pol,n); for(i=0; i<n; i++) { printf("[%d]=%d\n",i,pol[i]); } } 実行結果は [0]=-14646387 [1]=-1819410433 [2]=-224 array1d内では0を格納していますが、このようになりました。 どのようにすれば 0になるでしょうか? 回答よろしくお願いします。

専門家に質問してみよう