#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;
}
配列の問題です
配列の問題です
C言語を初めて勉強していて、やっと配列のところまできました。配列を使ってキーボードから入力された整数を大きい順にソートするプログラムの課題が出たのですが、実行すると大きい順に並べ変わって出てきた数字が1つ少ない状態になってしまいます。いろいろ調べてバブルソートの考え方にたどり着いて書いてみたのですがうまくいきません。どこを直したらいいのか具体的に教えてほしいです。
初心者でコメントがいろいろ入っていて見づらいと思いますがよろしくお願いします。
-
- 記事: 16
- 登録日時: 9年前
Re: 配列の問題です
後で私も一緒に考えさせていただきますが、
今、ぱっと見で思ったことを書かせていただきます。
初心者ならコメントをたくさん書くことはいいと思います。
私も初心者なのですが、未知のフレームワークやライブラリを初めて触るときは
コメントを書いて学びんでいきます。
あと、表示部のコードですが、 これだと i が 0 から始まり、
NUM - 1 つまり 9 よりも小さい間ループするという条件なので
0, 1, 2, 3, 4, 5, 6, 7, 8 という値を取っていきます。
9という値はこの条件では取らないので
表示される数字が1つ少なくなるのだと思います。
今、ぱっと見で思ったことを書かせていただきます。
過剰なコメントも良くないこともありますが、あゆ さんが書きました:初心者でコメントがいろいろ入っていて見づらいと思いますがよろしくお願いします。
初心者ならコメントをたくさん書くことはいいと思います。
私も初心者なのですが、未知のフレームワークやライブラリを初めて触るときは
コメントを書いて学びんでいきます。
あと、表示部のコードですが、 これだと i が 0 から始まり、
NUM - 1 つまり 9 よりも小さい間ループするという条件なので
0, 1, 2, 3, 4, 5, 6, 7, 8 という値を取っていきます。
9という値はこの条件では取らないので
表示される数字が1つ少なくなるのだと思います。
最後に編集したユーザー aridai1221 on 2016年7月02日(土) 21:57 [ 編集 1 回目 ]
Re: 配列の問題です
- ソートはNUM個の要素を対象にしているのに、入出力はNUM-1個しかしていないので、仮に適切な入力が与えられたとしても、
初期化されていない自動変数の値(不定)を使用し、未定義動作になります。
NUM-1回ではなくNUM回繰り返すようにしてください。 - 入力を正しく読み込めたかを確認するようにするといいでしょう。
- 何も工夫せずに標準入力から読み込んでいるので、リダイレクトなどの条件によってはキーボードから読み込めません。
キーボードからの入力に対応した端末プログラムを利用し、標準入力がキーボードに接続される条件で起動するようにするといいでしょう。 - 処理系が//を用いたコメントに対応していない場合は、/* ~ */を用いたコメントに書き換えるか消すといいでしょう。
- 処理系がscanf_sに対応していない場合は、scanfに置き換えるといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
-
- 記事: 16
- 登録日時: 9年前
Re: 配列の問題です
具体的ではないですが、あゆ さんが書きました:どこを直したらいいのか具体的に教えてほしいです。
直すべき場所はfor文の条件です。
大丈夫です。
ちょっと考えたら分かります。
ちょっと直したら
あゆさんのコード
ちゃんと動作しましたよ :)
Re: 配列の問題です
もし直してほしいのであれば、そのコードを提示していただけますか?あゆ さんが書きました:みなさんのアドバイス通りにforのところをいじってみたのですが、うまく作動してくれません・・・。
入力と期待する出力のデータもあると嬉しいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 配列の問題です
#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個になってしまいます。
ここを書き換えると入力は10個になるのですが、出力が9個の並べ替えと最後にマイナスのついた入力していない数が出てきてしまいます。
Re: 配列の問題です
入力の書式の%dの後に\nがあるので、10個目の数字を入力した後、次の空白でない文字またはEOFまで読み込む仕様になっています。
「自然」な挙動にするためには、この\nを消してください。
「自然」な挙動にするためには、この\nを消してください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: 配列の問題です
(NUM-1)個しか用意していないのにNUM個も入力させてはいけません。範囲外への書き込みが発生した場合、未定義動作になります。
「nつめとn+1つめの数字」とり「nつめとn+1つめ以降の数字」の方が正確ですね。
コメントは(NUM-1)回なのに、コードはNUM回なので、矛盾しています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)