こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

icpcの過去問

問題→
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1147&lang=jp

自分の回答→

#include <iostream>

using namespace std;
int numbers[105];

int order(int n,int num){

if(num==0){numbers[0]=n;}
else{
for(int i=0;i<num;i++){
if((numbers[num-(i+1)])>n){//cout << "here1";
numbers[num-i]=numbers[num-(i+1)];//cout << "here2";
numbers[num-(i+1)]=n;//cout << "here3";
}
}
}
return 0;
}//昇順に並べる


int main(){
int n;

while(cin>>n,n){ int count,answer;
for(int i=0;i<n;i++){int Numb;
cin >> Numb;if(i==2){cout << "here";}
order(Numb,i);
count++;
}//昇順に要素が並んだ

for(int i=1;i<count-1;i++){

answer += numbers[i];
}
answer = answer/(count-2);
cout << answer << endl;
}
}

実行結果→

3
7
6
5
Bus error

となってしまいます。最後の入力の時に、cinされずにbuserrorになるのですがなぜなのでしょうか。

投稿日時 - 2013-03-25 00:09:32

QNo.8010160

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

while(cin>>n,n)
って, 実際にはかなり危険なんですよ. この問題のように「最後に必ず 0 が入力される, そうでないようなものは知らん」って態度ならいいんだけど, 人間の入力を想定する場合は「想定しない入力」も考えておかないとダメ.

ということで, 普通はループの条件は
cin >> n
だけにしておき, ループ内部で「n が 0 かどうか」の判定をすることが多かったりする.

あと, for の条件が i<n で不十分な理由, あります? まぁ, そもそも 0 クリア自体が不要だけど.

む, order (って名前も変だが) の中もちょっと簡単にできそうだ.

投稿日時 - 2013-03-26 23:52:18

お礼

色々ありがとうございました!

投稿日時 - 2013-03-27 01:25:48

ANo.4

あとついでだけど,
while(cin>>n,n)
は何を意図した書き方なんでしょうか. こんな書き方を推奨する人間がいるとは想像もできないのですが.

投稿日時 - 2013-03-25 15:52:16

補足

>for文の条件
ここまで0にしとけば大丈夫だろって考えです。0にし忘れがないように多めにと思って・・・、とか言ったらまたお叱りを受けますね、すみません。

>while(cin>>n,n)
cin>>nを実行して、なおかつn!=0のときはループする、という意図です。

投稿日時 - 2013-03-26 15:06:33

ANo.3

bus error になる理由は #2 の通り.

あと, 書き換えたあとのプログラムで最後の for ループはなんで
for(int i=0;i<=n;i++)
なの?

投稿日時 - 2013-03-25 04:08:45

ANo.2

> cinされずにbuserror

プログラムを見ると、「cinが終わって」いるはずです。
最初の値3 がnになって、入力する個数
そのあと3つ値が入力されている。

> int count,answer;

とあるだけで、countもanswerも初期化されていません。
よって、何が入っているかわかりません。

例えば、countが200だったりします。すると

> for(int i=1;i<count-1;i++){
> answer += numbers[i];
> }

のループで、iは105以上の値を取ります。
numbers[105]と宣言されていますので、その範囲外をアクセスすることになります。

○ 変数は宣言しただけでは値は不定。他言語のように0やnullで初期化されたりしない(特定の場合を除く)。
○ 配列の範囲外をアクセスした場合、その動作は未定義。
 他言語のような「配列の範囲外エラー」になると決まっているわけではない。
 なにかのエラーになるかもしれないし、何事も無かったように動作するかもしれないし、ハードディスクが破壊されるかもしれない。
 何が起こっても「C/C++言語の仕様として『正しい』」

C/C++を使う上で覚えておかなければならない基本事項です。
ICPCの過去問という「応用問題」をやっているようですが、「応用問題」は「基礎」をマスターした上でのものです。
これまでの質問を見るかぎり、まだまだ基礎能力が不十分に見えます。
これくらいは自分で修正できるくらいに、基礎能力を高めるようにしてください。

投稿日時 - 2013-03-25 03:37:58

お礼

ありがとうございました!!

投稿日時 - 2013-03-26 14:38:32

ANo.1

なるべく変数は初期化してください.

投稿日時 - 2013-03-25 00:22:00

補足

ありがとうございました。
変数から見直して下記のようになり、無事自動添削でacceptedがもらえました。

#include <iostream>

using namespace std;
int numbers[105];

int order(int n,int num){

if(num==0){numbers[0]=n;}
else{
for(int i=0;i<num;i++){
if((numbers[num-(i+1)])>n){
numbers[num-i]=numbers[num-(i+1)];
numbers[num-(i+1)]=n;
}
else {numbers[num-i]=n;break;}
}
}
return 0;
}//昇順に並べる


int main(){
int n;

while(cin>>n,n){

for(int i=0;i<n;i++){int Numb;
cin >> Numb;
order(Numb,i);

}//昇順に要素が並んだ
/*for(int i=0;i<n;i++){
cout << numbers[i];
}*/
int answer=0;
for(int i=1;i<(n-1);i++){
answer += numbers[i];
}
answer = answer/(n-2);
cout << answer << endl;
for(int i=0;i<=n;i++){
numbers[i]=0;
}
}
}

変数の初期化含め色々と間違っていたのはわかるのですが、どうしてbuserrorが出ていたのかがわかりません。もしよろしければ教えてください。

投稿日時 - 2013-03-25 01:30:19