電子書籍の厳選無料作品が豊富!

/*
要素数がnoであるint型の配列vcの要素の最小値を返す関数
int min_of(const int vc[], int no) {}
を作成せよ。
*/

#include <stdio.h>

#define NUMBER 5

int min_of(const int vc[], int no)
{
int i;
int min = vc[0];

for( i = 1; i < no; i++ )
if (vc[i] < min)
min = vc[i];
return min;
}

int main(void)
{
int i;
int eng[NUMBER];
int mat[NUMBER];
int min_e, min_m;

printf("%d人の点数を入力して下さい\n", NUMBER);
for ( i = 0; i < NUMBER; i++ ) {
printf("[%d] 英語:", i + 1); scanf("%d", &eng[i]);
printf("   数学:"); scanf("%d", &mat[i]);
}

min_e = min_of(eng, NUMBER);
min_m = min_of(mat, NUMBER);

printf("英語の最低点=%d\n", min_e);
printf("数学の最低点=%d\n", min_m);

return 0;
}


質問:上記でわからない部分は
min_e = min_of(eng, NUMBER);
min_m = min_of(mat, NUMBER);
の部分と、ここで使用される、一番最初のint min_of(const int vc[], int no)です。

printfやscanfなど表示や変数&eng,&matに入力した値は表記される部分やdefine NUMBER 5とした部分は
5に置き換える意味はわかるのですが、このあたりのページから配列の受け渡しについて難しくてわかりません。

min_eという変数にたいして、min_of(eng,NUMBER)と上で定義したものを”呼ぶ”イメージはつくのですが
min_of(xxx)と記載してあれば、上に飛び下の抜き出した部分に移動すると思うのですが、
min_of(eng,NUMBER)をどのように下に扱えという意味なのでしょうか。?
min_of(eng,5)と一応置き換えます。*define NUMBER 5と宣言しているのでこれで正しいと思うのですが。。



int min_of(const int vc[], int no)
{
int i;
int min = vc[0];

for( i = 1; i < no; i++ )
if (vc[i] < min)
min = vc[i];
return (min);
}

最終的に上の部分にmin_of(eng.5)を行った結果をmin_eに代入してprintf(英語の最低点..,min_e)で
表示させているのはわかりますけど、肝心な部分がわかりません。

min_of(eng,NUMBER) -> min_of(eng,5)は上で定義された箇所に代入せよということでしょうか。

int min_of(const int vc[],int no) は代入され、
const int vc[]=eng,
int no= 5

という"代入"という意味になりますでしょうか。


そうなると、min_e=min_of(eng,NUMBER)の前のscanfで入力した値5回分の配列を
int min_of(const int vc[])に代入という意味でしょうか。
eng[0]=10
eng]1]=20
eng[2]=30..
eng[3]=40
eng]4]=50

-----
printf("%d人の点数を入力して下さい\n", NUMBER);
for ( i = 0; i < NUMBER; i++ ) {
printf("[%d] 英語:", i + 1); scanf("%d", &eng[i]);
printf("   数学:"); scanf("%d", &mat[i]);
}

min_e = min_of(eng, NUMBER);
min_m = min_of(mat, NUMBER);
---


するとmin_e = min_of(eng, NUMBER);のengは下の5個の配列を

eng[0]=10
eng]1]=20
eng[2]=30..
eng[3]=40
eng]4]=50

下のconst int vc[]に1つずつ代入という意味になりますでしょうか。
最初はeng[0]]=10,int no= 5の時、とeng[4]=50, int no=5と5回繰り返すという意味でしょうか。。

int min_of(const int vc[], int no)
{
int i;
int min = vc[0];

for( i = 1; i < no; i++ )
if (vc[i] < min)
min = vc[i];
return (min);
}

scanfで入力された5つの値をその後どのように処理されていくのか教えてください。
min_e = min_of(eng, NUMBER);
min_m = min_of(mat, NUMBER);
から上に行って、また下に降りているイメージはつくのですが、、どう代入されているのかよくわかりませんでした。
あと、const はなぜint vc[]の前につけないとだめなんでしょうか。

どなたか教えてください。よろしくおねがいします。

A 回答 (2件)

配列とポインタはC言語学習の最大の壁と言えるでしょう。


それだけで解説書ができるくらいです。


○ int min_of(const int vc[], int no)
と引数vcは配列を受けとるかのように見えますが、
これは
int min_of(const int * vc, int no)
とまったくの等価です。
vcが受けとるのは、ポインタです。

○ min_of(eng, NUMBER);
のように、配列名を使った場合、その配列の先頭要素のアドレスとして扱われます。
つまり
min_of(&(eng[0]), NUMBER);
と等価です。

○他の言語なら
min_of(eng)
とするところでしょう。
ですが、C言語の配列には、「配列の長さ」を調べる方法がありません。そのため
min_of(eng)
だけではどこまでが配列の内容なのかがわかりません。
そのため、配列の長さを別に指定するのが常套手段です。

○ const int vc[] は 「const int型」の配列 (あるいは「const int」へのポインタ) です。
const int でセットなので、書く位置はここです。
const int型は、読み取り専用の型です。

constを付けることで、誤書き込みをある程度防げます。
また、配列int A[10] を 引数const int vc[] で受けることはできますが、
また、配列const int A[10] を 引数 int vc[] で受けることはできません。
このような理由から、引数にconstを付けることはよくあります。
printfのマニュアルをよく見てください。 const char * になっているはずです。
    • good
    • 1
この回答へのお礼

回答ありがとうございます。ポインタについて今までずっと調べてました。
おかげでよくわかりました。最初にご回答いただいたので、とても助かりました。

お礼日時:2015/06/15 04:30

端的に言いますと、「関数は値」ということです。



min_e = min_of(eng, 5);
というのは、min_of(...) がただの数値であって、
その数値がmin_eという変数に代入される、という意味です。
で、min_of(...)がどういう数値かというと、
return(min); の「min」という数値になります。
つまり、return()の()の中身が、その関数の数値になるのです。

int func()
{
return(10);
}

int main()
{
int a;
a = func();
printf("%d\n", a);
exit(0);
}

なんて書くと、10と表示されます。
これが「代入」に関する疑問への答えです。

あと、min_of()関数の中の処理についてですが、
単純に引き渡された配列要素の中で最小の数値が入っているものを見つけ出しているだけです。
省略形で書かれているのでわかりにくいですが、
制御構造をちゃんとブロック付きで書くとわかりやすいです。

for( i = 1; i < no; i++ ) {
if (vc[i] < min) {
min = vc[i];
}
}
return (min);

つまり、全要素を順に、今まで見つけた最小と思われる数値(min)と比較し、
もっと小さいやつがあったら最少記録を更新する、
最後にこの関数の数値は、その最少記録にする、
というプログラムです。
    • good
    • 1

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