/* testscore */
#include <stdio.h>
#pragma warning(disable : 4996)
int main()
{
int sum = 0, p = 0, n = 0, max = 0, min = 100;
while(1){
printf("点数を入力(-1で終了)---");
scanf("%d", &p);
if(p == -1)
break;
sum += p;
n++;
if(p > max)
max = p;
if(p < min)
min = p;
if(n == 0)
printf("人数が0人の時は終了します\n");
return -1 ;
printf("合計点は%d 平均点は%5.1f 最高点は%d 最低点は%d 受験人数は%d人です\n",sum ,(double)sum / n ,max ,min );
}
printf("%d人の合計点は%dです\n",n,sum);
printf("平均点は%5.1fです\n",(double)sum / n);
printf("最高点は%d、最低点は%dです\n",max ,min);
return 0;
}
C言語、while文に関する初歩的な質問
-
ted
C言語、while文に関する初歩的な質問
点数を入力、-1を入力し終了するまでの最高点、最低点、平均点、合計点、人数を表示するプログラムなのですが、数字を入力した時点でプログラムが終了してしまいます。正しく動作させるためにはどこが間違っているのでしょうか。長いこと困ってます、よろしくお願いします。
- bitter_fox
- 記事: 607
- 登録日時: 15年前
- 住所: 大阪府
Re: C言語、while文に関する初歩的な質問
問題はココです。
if (n == 0)が真の時に実行されるのはprintf("人数が0人の時は終了します\n");だけで、return -1;は常に実行されてしまいます。
としてください。
こういったぶら下がり構文はバグの温床になるので極力{}で囲むようにしてはどうでしょうか?(僕はすべて{}で囲むようにしています。)
あと、インデントによってsum += p;以降の分もif(p == -1)のブロックに見えてしまうので、もっと厳密なインデントを行うことをお勧めします。
[hr][追記]
厳密にインデントすると次のような感じになります。
/* testscore */
#include <stdio.h>
#pragma warning(disable : 4996)
int main()
{
int sum = 0, p = 0, n = 0, max = 0, min = 100;
while(1){
printf("点数を入力(-1で終了)---");
scanf("%d", &p);
if(p == -1)
break;
sum += p;
n++;
if(p > max)
max = p;
if(p < min)
min = p;
if(n == 0)
printf("人数が0人の時は終了します\n");
return -1;
printf("合計点は%d 平均点は%5.1f 最高点は%d 最低点は%d 受験人数は%d人です\n",sum ,(double)sum / n ,max ,min );
}
printf("%d人の合計点は%dです\n",n,sum);
printf("平均点は%5.1fです\n",(double)sum / n);
printf("最高点は%d、最低点は%dです\n",max ,min);
return 0;
}
-
ted
Re: C言語、while文に関する初歩的な質問
whileに-1が返っていたのですか、bitter_foxさん、どうもありがとうございました!
僕も{}を必ずつけるようにします。お手数掛けました。
僕も{}を必ずつけるようにします。お手数掛けました。
- bitter_fox
- 記事: 607
- 登録日時: 15年前
- 住所: 大阪府
Re: C言語、while文に関する初歩的な質問
whileに-1が返っているのではなく戻り値を-1としてmain関数を抜けるという意味になってます。ted さんが書きました:whileに-1が返っていたのですか、bitter_foxさん、どうもありがとうございました!
僕も{}を必ずつけるようにします。お手数掛けました。
その証拠に、whileの外に書かれている が実行されていないはずです。(もしwhileだけを抜けた場合はこの三文+return 0;が実行されているはずです。)
-
ted
Re: C言語、while文に関する初歩的な質問
bitter_foxさん度々ありがとうございます。
最初の入力で-1を入力した場合に「人数が0人の時は終了します」を正しく表示するために
とwhile文ブロックの後にif(n == 0)のソースを持ってくると正しく、
この3文が表示されずに終わりました。
しかしreturnについての認識が甘いようで、今ひとつ理解できません。 この部分のreturnに何の数字を入れなくても「人数が0人の時は終了します」が表示され正しく終了してしまいます。
サンプルプログラムにはreturn -1 とされていたのでそれに倣ったのですがここにきてreturnの正確な役割がわからなくなってしまいました。
(問題の回答プログラム)
こちらもif (n == 0)のときのreturn -1を0に変えても8に変えても入力しなくても正しく終了します。
何故なのかわかりません。
最初の入力で-1を入力した場合に「人数が0人の時は終了します」を正しく表示するために
printf("合計点は%d 平均点は%5.1f 最高点は%d 最低点は%d 受験人数は%d人です\n",sum ,(double)sum / n ,max ,min ,n);
}
if(n == 0){
printf("人数が0人の時は終了します\n");
return -1;}
printf("%d人の合計点は%dです\n",n,sum);
printf("平均点は%5.1fです\n",(double)sum / n);
printf("最高点は%d、最低点は%dです\n",max ,min);
しかしreturnについての認識が甘いようで、今ひとつ理解できません。 この部分のreturnに何の数字を入れなくても「人数が0人の時は終了します」が表示され正しく終了してしまいます。
サンプルプログラムにはreturn -1 とされていたのでそれに倣ったのですがここにきてreturnの正確な役割がわからなくなってしまいました。
(問題の回答プログラム)
/* program53.c */
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
int main()
{
int max = 0, min = 100, x, n = 0, sum = 0;
while (1) {
printf("点数---- ");
scanf("%d", &x);
if (x == -1)
break;
sum += x;
if (x >= max)
max = x;
if (x <= min)
min = x;
n++;
printf("n = %d, max = %d, min = %d, sum = %d\n",
n, max, min, sum);
}
if (n == 0) {
printf("受験者数が0の時は計算できません\n");
return -1;
}
printf("最低点 = %d点、最高点 = %d点、受験者数 = %d人、平均点 = %5.1f点\n",
min, max, n, (double)sum / n);
return 0;
}
何故なのかわかりません。
- bitter_fox
- 記事: 607
- 登録日時: 15年前
- 住所: 大阪府
Re: C言語、while文に関する初歩的な質問
return文は関数ブロックを抜けて呼び出し元に値を返すために用います。
main関数の場合はOSやその他の呼び出し元に対して値を返すことになります。
例えば、Windowsからexeファイルをクリックして実行した場合はWindowsに対して値が返されます。(厳密には色々なところを通って返っているわけですが・・・)
ですが、Windowsはこの値を無視してますので特に気にする必要はありません。
また、バッチファイルから呼び出した場合はそのバッチファイルに対して値が返されますので、その戻り値を用いて実行結果(正常終了か異常終了か)を判定したりします。
http://www.geekpage.jp/programming/c/return-main.php
一般に正常終了した場合は0を異常終了した場合は0以外の値を返します。
returnのあとに何も書かなかった時の動作がC言語の規格で定まっているのは戻り値がvoidの関数(つまり何も値を返さない関数)の中で使われた場合のみです。(その時の動作は単に関数を抜けるという意味)
もし、それ以外の関数内で使用された場合にどういった値が返されるのかはコンパイラに依存します。
ですので、戻り値がint型のmain関数内でそのようなreturn文を書くのはよろしくありません。
Re: C言語、while文に関する初歩的な質問
戻り値のあるreturn文は、そのreturn文が属している関数の呼び出し元に対し、
戻り値の値によって異なる動作をさせるために用います。
今回の場合、「そのreturn文が属している関数」はmain関数を指します。
では、「そのreturn文が属している関数の呼び出し元」、つまりmain関数の呼び出し元とは何でしょうか。
それは、
Windows/MS-DOS系のOSではバッチファイル、
UNIX系のOSではシェルスクリプト
などのことをいいます。
元々のサンプルコードでは、main関数内で
return 0;
return -1;
という2種類の値を使い分けています。これは、
先ほど書きましたバッチファイルやシェルスクリプトに対し、
return 0→正常終了
return -1→異常終了
であることを知らせるためのものです。
知らせを受けたバッチファイルやシェルスクリプトでは、呼び出したプログラムの終了結果(サンプルコードでは0か-1)によって、
その後の処理を変更するようなロジックが入ることになります。
バッチファイルやシェルスクリプトが存在せず、単独で動かす場合には
return 0;
return -1;
の両者(あるいは、質問者さんが書かれたretun 8;)には見かけ上の違いは生じません。
0や-1(や8)という戻り値を受け取る側が存在しないためです。
なお、int型の戻り値を求めているmain関数で、単に
return;
と書いた場合、呼び出し元には不定値が返ります。
呼び出し元の動作をどう規定すればよいかがわからなくなりますので、あまり推奨できません。
戻り値の値によって異なる動作をさせるために用います。
今回の場合、「そのreturn文が属している関数」はmain関数を指します。
では、「そのreturn文が属している関数の呼び出し元」、つまりmain関数の呼び出し元とは何でしょうか。
それは、
Windows/MS-DOS系のOSではバッチファイル、
UNIX系のOSではシェルスクリプト
などのことをいいます。
元々のサンプルコードでは、main関数内で
return 0;
return -1;
という2種類の値を使い分けています。これは、
先ほど書きましたバッチファイルやシェルスクリプトに対し、
return 0→正常終了
return -1→異常終了
であることを知らせるためのものです。
知らせを受けたバッチファイルやシェルスクリプトでは、呼び出したプログラムの終了結果(サンプルコードでは0か-1)によって、
その後の処理を変更するようなロジックが入ることになります。
バッチファイルやシェルスクリプトが存在せず、単独で動かす場合には
return 0;
return -1;
の両者(あるいは、質問者さんが書かれたretun 8;)には見かけ上の違いは生じません。
0や-1(や8)という戻り値を受け取る側が存在しないためです。
なお、int型の戻り値を求めているmain関数で、単に
return;
と書いた場合、呼び出し元には不定値が返ります。
呼び出し元の動作をどう規定すればよいかがわからなくなりますので、あまり推奨できません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
-
ted
Re: C言語、while文に関する初歩的な質問
bitter_fox さん、boxさん、どうもありがとうございます!
この場合のreturnはプログラムの正(0)否(0以外)をバッチファイルに伝えてmain関数を抜ける、ということが理解できました。
さらにmain関数はint型の関数なのでreturnに数字を書かないのはバッチファイルがどう動作するかわからなくなるので危険、ということですね。
この場合のreturnはプログラムの正(0)否(0以外)をバッチファイルに伝えてmain関数を抜ける、ということが理解できました。
さらにmain関数はint型の関数なのでreturnに数字を書かないのはバッチファイルがどう動作するかわからなくなるので危険、ということですね。