ページ 1 / 1
配列の問題です
Posted: 2016年7月02日(土) 21:07
by あゆ
C言語を初めて勉強していて、やっと配列のところまできました。配列を使ってキーボードから入力された整数を大きい順にソートするプログラムの課題が出たのですが、実行すると大きい順に並べ変わって出てきた数字が1つ少ない状態になってしまいます。いろいろ調べてバブルソートの考え方にたどり着いて書いてみたのですがうまくいきません。どこを直したらいいのか具体的に教えてほしいです。
コード:
#include <stdio.h>
#define NUM 10
int main(void)
{
int n[NUM]; //NUM個の型を用意する
int tmp; //交換する際の一時代入につかう
int i; //繰り返し
int t, s; //比較の際つかう
//数字を入力させる
printf("%d個の整数を入力してください。\n",NUM);
for (i = 0; i < NUM - 1; i++) {
scanf_s("%d\n", &n[i]);
}
printf("\n大きい順に並べ替えます。\n\n");
//forの二重ループ
//1つめと2つめの数字を比較して大きい順にならべかえる
//2つめと3つめの数字を比較して大きい順にならべかえる
//(NUM-1)番目とNUM番目まで繰り返す
for (t = 0; t < NUM; ++t)
for (s = t + 1; s < NUM; ++s) {
if (n[s] > n[t]) {
tmp = n[s]; //変数tmpにn[s]を代入
n[s] = n[t]; //変数n[s]にn[t]を代入
n[t] = tmp; //変数n[t]にtmp(n[s])を代入
//入れ替えの完了
}
}
//大きい順に表示させる
//forでNUM-1回繰り返す
for (i = 0; i < NUM - 1; ++i) {
printf("%d\n", n[i]);
}
return 0;
}
初心者でコメントがいろいろ入っていて見づらいと思いますがよろしくお願いします。
Re: 配列の問題です
Posted: 2016年7月02日(土) 21:55
by aridai1221
後で私も一緒に考えさせていただきますが、
今、ぱっと見で思ったことを書かせていただきます。
あゆ さんが書きました:初心者でコメントがいろいろ入っていて見づらいと思いますがよろしくお願いします。
過剰なコメントも良くないこともありますが、
初心者ならコメントをたくさん書くことはいいと思います。
私も初心者なのですが、未知のフレームワークやライブラリを初めて触るときは
コメントを書いて学びんでいきます。
あと、表示部のコードですが、
コード:
//大きい順に表示させる
//forでNUM-1回繰り返す
for (i = 0; i < NUM - 1; ++i) {
printf("%d\n", n[i]);
}
これだと i が 0 から始まり、
NUM - 1 つまり 9 よりも小さい間ループするという条件なので
0, 1, 2, 3, 4, 5, 6, 7, 8 という値を取っていきます。
9という値はこの条件では取らないので
表示される数字が1つ少なくなるのだと思います。
Re: 配列の問題です
Posted: 2016年7月02日(土) 21:56
by みけCAT
- ソートはNUM個の要素を対象にしているのに、入出力はNUM-1個しかしていないので、仮に適切な入力が与えられたとしても、
初期化されていない自動変数の値(不定)を使用し、未定義動作になります。
NUM-1回ではなくNUM回繰り返すようにしてください。
- 入力を正しく読み込めたかを確認するようにするといいでしょう。
- 何も工夫せずに標準入力から読み込んでいるので、リダイレクトなどの条件によってはキーボードから読み込めません。
キーボードからの入力に対応した端末プログラムを利用し、標準入力がキーボードに接続される条件で起動するようにするといいでしょう。
- 処理系が//を用いたコメントに対応していない場合は、/* ~ */を用いたコメントに書き換えるか消すといいでしょう。
- 処理系がscanf_sに対応していない場合は、scanfに置き換えるといいでしょう。
ちなみに、これはバブルソートではなく
選択ソートですね。
Re: 配列の問題です
Posted: 2016年7月02日(土) 22:20
by aridai1221
あゆ さんが書きました:どこを直したらいいのか具体的に教えてほしいです。
具体的ではないですが、
直すべき場所は
for文の条件です。
大丈夫です。
ちょっと考えたら分かります。
ちょっと直したら
あゆさんのコード
ちゃんと動作しましたよ :)
Re: 配列の問題です
Posted: 2016年7月03日(日) 09:37
by あゆ
みなさんのアドバイス通りにforのところをいじってみたのですが、うまく作動してくれません・・・。
Re: 配列の問題です
Posted: 2016年7月03日(日) 09:52
by みけCAT
あゆ さんが書きました:みなさんのアドバイス通りにforのところをいじってみたのですが、うまく作動してくれません・・・。
もし直してほしいのであれば、そのコードを提示していただけますか?
入力と期待する出力のデータもあると嬉しいです。
Re: 配列の問題です
Posted: 2016年7月03日(日) 11:14
by あゆ
コード:
#include <stdio.h>
#define NUM 10
int main(void)
{
int n[NUM - 1]; //(NUM-1)個の型を用意する
int tmp; //交換する際の一時代入につかう
int i; //繰り返し
int t, s; //比較の際つかう
//数字を入力させる
printf("%d個の整数を入力してください。\n",NUM);
for (i = 0; i < NUM; i++) {
scanf_s("%d\n", &n[i]);
}
printf("\n大きい順に並べ替えます。\n\n");
//forの二重ループ
//1つめと2つめの数字を比較して大きい順にならべかえる
//2つめと3つめの数字を比較して大きい順にならべかえる
//(NUM-1)番目とNUM番目まで繰り返す
for (s = 0; s < NUM; s++)
for (t = s + 1; t < NUM; t++) {
if (n[t] > n[s]) {
tmp = n[t]; //変数tmpにn[s]を代入
n[t] = n[s]; //変数n[s]にn[t]を代入
n[s] = tmp; //変数n[t]にtmp(n[s])を代入
//入れ替えの完了
}
}
//大きい順に表示させる
//forで(NUM-1)回繰り返す
for (i = 0; i < NUM; i++) {
printf("%d\n", n[i]);
}
return 0;
}
入力する数字は何でもいいです。
出力が上から順番に大きくなっていてほしいです。
このコードにすると入力が11個
出力が10個になってしまいます。
コード:
//数字を入力させる
printf("%d個の整数を入力してください。\n",NUM);
for (i = 0; i < NUM - 1; i++) {
scanf_s("%d\n", &n[i]);
}
ここを書き換えると入力は10個になるのですが、出力が9個の並べ替えと最後にマイナスのついた入力していない数が出てきてしまいます。
Re: 配列の問題です
Posted: 2016年7月03日(日) 12:23
by みけCAT
入力の書式の%dの後に\nがあるので、10個目の数字を入力した後、次の空白でない文字またはEOFまで読み込む仕様になっています。
「自然」な挙動にするためには、この\nを消してください。
Re: 配列の問題です
Posted: 2016年7月03日(日) 15:25
by かずま
[quote="あゆ" id=3,18149,138739]
コード:
int n[NUM - 1]; //(NUM-1)個の型を用意する
元は NUM だったものを NUM - 1 に変更した理由を説明してください。
Re: 配列の問題です
Posted: 2016年7月03日(日) 15:42
by みけCAT
あゆ さんが書きました:コード:
int n[NUM - 1]; //(NUM-1)個の型を用意する
コード:
//数字を入力させる
printf("%d個の整数を入力してください。\n",NUM);
for (i = 0; i < NUM; i++) {
scanf_s("%d\n", &n[i]);
}
(NUM-1)個しか用意していないのにNUM個も入力させてはいけません。範囲外への書き込みが発生した場合、
未定義動作になります。
あゆ さんが書きました:コード:
//forの二重ループ
//1つめと2つめの数字を比較して大きい順にならべかえる
//2つめと3つめの数字を比較して大きい順にならべかえる
//(NUM-1)番目とNUM番目まで繰り返す
「nつめとn+1つめの数字」とり「nつめとn+1つめ
以降の数字」の方が正確ですね。
あゆ さんが書きました:コード:
//大きい順に表示させる
//forで(NUM-1)回繰り返す
for (i = 0; i < NUM; i++) {
printf("%d\n", n[i]);
}
コメントは(NUM-1)回なのに、コードはNUM回なので、矛盾しています。