次のような問題があって、プログラミングしてみたのですが、
コンパイルすると永久ループになってしまいます。
また、入力されるはずの整数が表示されません。
どうすればよいか教えていただけると助かります。
よろしくお願いします。
整数を順番に入力し、負の数が入力されたら、それまでに入力された非負の整数を、 入力された順番とは逆に全角空白で区切って出力するプログラムを作成しなさい。
自動評価の都合上、上記以外は表示しないこと。なお、入力は最大10回とする。
【0 1 2 3 4 -1 が入力された場合の表示例】
4 3 2 1 0
**************************************
#include <stdio.h>
int main(void) {
int num[10];
int n;
for(n=1;n<11;n++){
printf("整数入力:¥n");
scanf ("%d", &num[n]);
if(num[n]<0){
for(n=10;n>0;n--){
printf("%d ",num[n]);
}
}
}
}
A 回答 (8件)
- 最新から表示
- 回答順に表示
No.8
- 回答日時:
ついでなのでもう一言。
こういう場合、「どうすれば良いか」を聞くより、「なぜこうなるか(無限ループしてしまうのか)」を理解する方がはるかに大切です。
No.3 で指摘されていますが。
そして、それは、「使っている変数を書き出して、プログラムを一行ずつ追いかけて、変数がどう変わり、どういう順序で処理されるか」と(No.4 では「頭で考えれば分かると書かれていますが)「紙に書き出してみれば」わかります。
実際、No.1 の回答へのお礼で
「ループを分離してすっきりしてわかりやすくなりました」と書かれていますが、元のプログラムは、単に「すっきりしていない、わかりにくい」だけではなく、明らか無限ループするプログラムです。
わかりにくいプログラムがわかりやすくなったというだけではないのです。
それは、慣れた人から見ると、「このプログラムはひどい」というレベルの間違いですが、プログラムを書き始めた人が、問題文を読みながら、(本当は、「設計」という行為が入るのだが)一行ずつ組み立てると、「まあ、やってしまうかもしれないな」というプログラムです。
ですから、なぜ、最初のプログラムが無限ループになるのか、理解しないでおくと、「初心者がやってしまいがちなとんでもないプログラム」という状態から抜け出すのにかなり苦労することになります。
※まあ、紙に書き出さなくても、「デバッガ」の使い方を覚えて、実行をトレースしてみるのも、役に立つと思います。
No.7
- 回答日時:
Cに特有な話があるのでひとつだけ。
まず、for は、
for (i = 0; i < 10; i++)
というパターンで使われることが多いのですが、for自体は、「(たとえば)10回繰り返す」ということを表現するだけのものではありません。
あくまでも、for(式1; 式2; 式3) ということで、
1)ループに先立って、式1 を実行する
2)式2が成立していたら、ループの処理を行う
3)ループの処理が1回分終わったら、式3を実行する。
4) 2) に帰る
という処理をするものです。
だから、
for(i = 0; i < 10; i++)
が、
1) 最初に i に 0 を代入し、
2) i < 10 が成立している間ループを繰り返し
3) ループが終わるごとに i++ を実行する
という意味になるのです。
for(n--; n>=0 ; n--)
の、式1,式2,式3がどれになるか確認して、どういう処理をするのか、確かめてみてください。
for の 式1は、必ず代入という決まりはないです。
No.6
- 回答日時:
>結果表示のループのn--を何もしない。
にするとどうなるのか…。微妙に判りにくいかな。
for(n--; n>=0 ; n--){
を
for(; n>=0 ; n--){
にしてみる。
for(n = 9; n>=0 ; n--){
にしてみる。
# 10ではないので注意。
for(n = 0; n>=0 ; n--){
にしてみる。
for(n = 0; n < 10 ; n++){
にしてみる。
などなど……。
No.5
- 回答日時:
>最初の入力値が入るのはどうしてか教えていただけますか?
>はじめから1引くと、最初の値が消えてしまうのではと思うのですが。
最初の入力値ってなんです?
最初の値が消えるってのもなんのこと言ってます?
頭の中で実行(中の動作を想定)でききないなら、あらゆるところにprintf()などで変数の値を出力するいわゆるprintfデバッグをするか、
デバッガのステップ実行で1つずつ追いかけてみたらどうですか。
int num[10], n, i;
for(n = 0; n < 10; n++) {
printf("\n n = %d/num[]=", n);
for(i = 0;i < 10;i++) printf("%d ", num[i]);
printf("\n");
scanf("%d", &num[n]);
printf("\n num[]=");
for(i = 0;i < 10;i++) printf("%d ", num[i]);
printf("\n");
if (num[n] < 0) {
break;
}
}
printf("\n loop-end\n n = %d/num[]=", n);
for(i = 0;i < 10;i++) printf("%d ", num[i]);
printf("\n");
for(n--; n>=0 ; n--){
printf(" num[%d]=%d", n, num[n]);
}
こんな感じですかね。
scanf()で値を入れる前後でnの値とnum[]配列の全部を表示します。
で、ループを抜けた後でもnの値とnum[]配列の全部を、結果表示のループ中もnの値を出力します。
# num配列は未初期化なんでscanf()で値を取り込んでいない箇所の値は不定値(プロセス起動ごとに値が変わるかも知れない)になります。
# 最初のループの前に特定の値にしておくといいかと。
結果表示のループのn--を何もしない。にするとどうなるのか…。
とかいろいろ変更してみるといいでしょう。
No.3
- 回答日時:
「どうすればよいか」の前に「どうしてそうなるのか」を理解してください.
この回答への補足
以下のようなプログラムもありました。
そこで、2つめのfor文で、
初期値が n--なのに、
最初の入力値が入るのはどうしてか教えていただけますか?
はじめから1引くと、最初の値が消えてしまうのではと思うのですが。
よろしくお願いします。
#include <stdio.h>
int main(void){
int num[10], n;
for (n = 0; n < 10; n++) {
scanf("%d", &num[n]);
if (num[n] < 0) {
break;
}
}
for(n--; n>=0 ; n--){
printf(" %d",num[n]);
}
}
No.2
- 回答日時:
というわけで、
#include <stdio.h>
int main(void)
{
int num[10], n;
for (n = 0; n < 10; n++) {
printf("整数入力:¥n");
scanf("%d", &num[n]);
if (num[n] < 0) {
break;
}
}
while (n--) {
printf("%d%s", num[n], (n == 0) ? "" : " ");
}
return 0;
}
No.1
- 回答日時:
>コンパイルすると永久ループ
「実行すると」ですね?
さて、
>int num[10];
このように定義した配列で、有効な添字は0~9の10個です。
num[10]
の10とは、num[10]にアクセスできる、という意味ではありません。
領域を0から9までの10個確保する、という意味です。
ところが、
>for(n=1;n<11;n++){
>for(n=10;n>0;n--){
nが10の場合があるため、配列の定義範囲外の領域へアクセスしようとしています。
まずは、ここを修正してみてはどうでしょうか。
また、for文によるループの仕方も正しくないように見えます。
入力するループと逆順に出力するループを入れ子にするのではなく、
完全に分離してみてはどうでしょうか。
ご回答ありがとうございます。
ループを分離してみました。
このほうがすっきりしてわかりやすくなりました。
nの範囲も修正してみました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語 3 2022/10/04 15:07
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語階乗の総和を求める
-
#if 1 #elseの意味について
-
while文について、c言語...
-
for文の中にswitch文はいれられ...
-
構文エラー";"が型の前にあり...
-
配列を関数に渡す方法
-
c言語for文
-
C言語 重複しない4ケタの乱数...
-
初心者です。for文、if文を使っ...
-
C言語プログラムが理解できなくて…
-
if文の中に
-
C言語でのトランプシャッフルに...
-
switch文をif文に変換
-
c言語プログラミングで1から100...
-
C言語 偶数判定
-
配列を使って魔方陣
-
C言語です
-
C言語の二分法のプログラムにつ...
-
1年単利金利 0.2% の A銀行と...
-
直角三角形を表示するプログラム
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
for文の中にswitch文はいれられ...
-
#if 1 #elseの意味について
-
プログラミングで二番目に大き...
-
getcの改行判定
-
C言語プログラムが理解できなくて…
-
C言語 数字以外を入力させない...
-
配列を関数に渡す方法
-
配列を使って魔方陣
-
初心者です。for文、if文を使っ...
-
c言語for文
-
c言語で平均をだす
-
while文について、c言語...
-
scanf関数を用いての加減乗除%...
-
行列をべき乗させるプログラム
-
c言語プログラミングで1から100...
-
C言語階乗の総和を求める
-
scanfが実行されません
-
階乗のプログラム!!
-
C言語の二分法のプログラムにつ...
おすすめ情報