次のような問題があって、プログラミングしてみたのですが、
コンパイルすると永久ループになってしまいます。
また、入力されるはずの整数が表示されません。
どうすればよいか教えていただけると助かります。
よろしくお願いします。
整数を順番に入力し、負の数が入力されたら、それまでに入力された非負の整数を、 入力された順番とは逆に全角空白で区切って出力するプログラムを作成しなさい。
自動評価の都合上、上記以外は表示しないこと。なお、入力は最大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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
配列を使って魔方陣
-
プログラミングで二番目に大き...
-
c言語で平均をだす
-
C言語 プログラム
-
プログラミングの配列で
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
2の補数を計算するプログラム
-
マイナスからプラスへ転じた時...
-
Aの値からBの値を除するとは??
-
ある商品のロス率を5%見込み、...
-
反転した数値を表示させるやり方
-
O(n log n)について2
-
C言語 関数プロトタイプ宣言の...
-
正負を反転させて出力するプロ...
-
visualstudio C# テキストボッ...
-
C言語を実行すると-infが出てき...
-
EXCELの分散分析表のP-値が....
-
hit&bolwのプログラミングがで...
-
プログラムでの数字につく”f”の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
プログラム
-
#if 1 #elseの意味について
-
for文の中にswitch文はいれられ...
-
配列を使って魔方陣
-
getcの改行判定
-
配列を関数に渡す方法
-
プログラミングで二番目に大き...
-
C言語階乗の総和を求める
-
scanf関数を用いての加減乗除%...
-
C言語で電卓を作成する。
-
C言語 プログラム
-
C言語の二分法のプログラムにつ...
-
C言語のwhile文を使った素数判...
-
while文について、c言語...
-
10進数からN進数に変換するプロ...
-
C言語です
-
C言語・アルゴリズムの勉強法(...
-
C言語のプログラミング (基礎...
-
全角文字の判定
おすすめ情報