たびたび申し訳ありません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YYY

たびたび申し訳ありません。

#1

投稿記事 by YYY » 18年前

これだけ聞いてばかりだと自分の力にならないような気がしますが・・どうしてもわからないので教えてください。私が意図する出力は、
2001 .234
2002 .332
2003 .320
2004 .343
2005 .300
2006 .256
2007 .323

なんですが以下のプログラム


#include <stdio.h>

int main(void)
{
int at_bats[7];
int base_hit[7];
int year;
float average;
int number;

at_bats[0]=692; base_hit[0]=242;
at_bats[1]=647; base_hit[1]=208;
at_bats[2]=679; base_hit[2]=212;
at_bats[3]=704; base_hit[3]=262;
at_bats[4]=679; base_hit[4]=206;
at_bats[5]=695; base_hit[5]=224;
at_bats[6]=678; base_hit[6]=238;

average = base_hit[numbe[/url]/at_bats[numbe[/url];


printf("year\n");
for(year = 2001; year < 2008 ; year++){
printf("%2d\n", year);
for(number = 0; number < 7 ; number++){
printf("%2d\n", average);

}
}



という風に入力すると
year
2001
0
0
0
0
0
0
0
2002
0
0
0
0
0
0
0
2003
0
0
0
0
0
0
0
2004
0
0
0
0
0
0
0
2005
0
0
0
0
0
0
0
2006
0
0
0
0
0
0
0
2007
0
0
0
0
0
0
0
となります。
0になる原因は分かっているので無視してもいいですが意図するようにならないので困ります。
{}の位置とかを変えてforの外に出してしまうと
2001
2002
2003
2004
2005
2006
2007
0
0
0
0
0
0
と下側に表示されてしまいます。意図する動作に出力される方法を教えてください。
お願いします。

YYY

Re:たびたび申し訳ありません。

#2

投稿記事 by YYY » 18年前

すみません。配列の数字とaverageの値は合いませんが気にしないでください。

miyaza

Re:たびたび申し訳ありません。

#3

投稿記事 by miyaza » 18年前

そもそもソースをコンパイルできません。
括弧の数が足りなくて。

average = base_hit[numbe[/url]/at_bats[numbe[/url];
は、7回計算する必要がありますね。

average = base_hit[numbe[/url]/at_bats[numbe[/url];
int型同士を割ってその結果をaverageに入れていますね。
例えば 242/692では0.35となりますが、int型なので0となりそれがaverageに入ります。
ですから0となります。

printf("%2d\n", average);
averageはfloat型なので%dではまずいですね。

意図した出力というのが数字だけでは良く分かりません。
文章で説明してください。

問題点をならべてみましたが・・・・・・どうでしょう?

管理人

Re:たびたび申し訳ありません。

#4

投稿記事 by 管理人 » 18年前

先ほどのトピで気になったのですが、括弧の対応や有効範囲の対応は理解されていますか?
----------------------------------------

①;
for(i=0;i<3;i++){
    ②;
}
③;

----------------------------------------

①;
for(i=0;i<3;i++)
    ②;
③;

----------------------------------------


for(i=0;i<3;i++){
①;
②;
}
③;


----------------------------------------


 
この3種類ともどのように処理が行わるかはっきりわかりますか?
ソースファイルのコピペで括弧をコピーし忘れただけならいいのですが、
括弧の始まりの数だけ終わりの括弧も必要です。
括弧は有効範囲を示します。
括弧の外に出したり入れたりして、偶然うまく行くのを待つのではなく、
どのように書けばどのような処理が出来るか考えてから正確なコードを
書くことが解決への最短経路だと思います。

year -> average -> year -> average -> year -> average -> の順番で表示したいのなら、
どちらかだけループに入れてしまったのでは無理ですね。


for(i=0;i<2;i++){
    ①;
    for(j=0;j<3;j++){
        ②;
    }
    ③;
}

このプログラムはどのような順序で処理されるか、考えてみてください。

YYY

Re:たびたび申し訳ありません。

#5

投稿記事 by YYY » 18年前

一番最初の奴は①が実行され②でループし条件を満たしたら③が実行される。
次の奴はコンパイル不可能?
最後の奴は①、②、③すべてでループでしょうか?
やはり適当は駄目ですよね・・・。反省します。

簡単に言ってしまうと。
年度の右に値を表示させたいだけです。for文の中に入れて前は解決できたんですがね・・。
やはりアベレージを7回計算しないとダメなんでしょうか?0~6を次々に入れてfor文で
書けないんですかね?

管理人

Re:たびたび申し訳ありません。

#6

投稿記事 by 管理人 » 18年前

仰った答えは3つとも不正解です。

やはり括弧の対応というのは、プログラムを書く上で基本中の基本で、それがわかってないとかけないので、
ここで質問するより先に、入門サイトで勉強された方が近道だと思います。

1番は意味は解っていらっしゃるのかもしれませんが、言葉が違います。

厳しい事を言うようですが、ここで、仮に有力な回答や、答えを聞いても、結局理解には繋がらないと思います。

先ほども私が言いましたとおり、括弧は有効範囲を示します。
3において、括弧閉じている③がループ処理される事はありません。

最低限if文の書き方、for文の書き方、括弧の有効範囲だけは、先ほどお伝えしたサイトなどで勉強してください。

管理人

Re:たびたび申し訳ありません。

#7

投稿記事 by 管理人 » 18年前

①;
for(i=0;i<3;i++){
    ②;
}
③;

このプログラムは
① ②②② ③
の順で行われます。

----------------------------------------

①;
for(i=0;i<3;i++)
    ②;
③;

括弧を書かなかったら「次のセミコロンまで」が条件文の有効範囲と成りますので、②までがforの有効範囲です。
つまり
1と同じ処理順序になります。

----------------------------------------


for(i=0;i<3;i++){
①;
②;
}
③;

単純に字下げをしなかったバージョンです。括弧の有効範囲は括弧の始まりから終わりまでですから
forの有効範囲は①②の2つ。③は有効範囲ではないので、ループされません。
よって
①②①②①② ③
となります。
 
for文にしてもwhile文にしても、「条件を満たしている間」ループします。
つまり条件を満たさなくなったらループを出ます。
for(i=0;i<2;i++){
は何を意味しているか、

for(①;②;③)

①は初期設定
②は継続可能条件
③は変数内容の変更

を意味します。もちろん違う書き方も出来ますが。
②の継続可能条件を満たさなくなったら終了です。
i<2を終了する時、iは2になっているでしょう。

では

for(i=0;i<2;i++){
    ①;
    for(j=0;j<3;j++){
        ②;
    }
    ③;
}

の順番を考えてみてください。
また、ループを抜けた時の、iとjの値は何になっているか考えてみてください。

YYY

Re:たびたび申し訳ありません。

#8

投稿記事 by YYY » 18年前

有効範囲ですか。分りました。
それでは私のプログラムではyear、averageのいずれもがループしてしまうんですね。
しかしfor文の括弧を閉じ、そのあとまたfor文を書くとyearの下にaverageが表示されるんですよね。
何とかaverageをyearの右に表示させたいです。それさえわかればこのプログラムはできそうです。

管理人

Re:たびたび申し訳ありません。

#9

投稿記事 by 管理人 » 18年前

私の回答は脱線しているわけではないです。
最初からよくお読みになったら解ると思いますが、答えを自分で導き出していただく為にこのような事を書いています。
私が答えを書く事は簡単ですが、それでは意味が無いので。
面倒でしょうが、考えてみましょう。
for(i=0;i<2;i++){
    ①;
    for(j=0;j<3;j++){
        ②;
    }
    ③;
}

この順番がわかれば

for(i=0;i<2;i++){
    printf("A");
    for(j=0;j<3;j++){
        printf("B");
    }
    printf("C");
}

これで何が表示されるかわかりますよね?

管理人

Re:たびたび申し訳ありません。

#10

投稿記事 by 管理人 » 18年前

>それさえわかればこのプログラムはできそうです。

miyazaさんが仰っていますが、まだおかしな場所は沢山あり、それだけでは解決しません。

特に
アベレージの部分は
numberには何も入っていない、むしろ参照してはいけないものが入っている要素をさす形になっているので、非常にまずいです。

プログラムを書く前に、平均ってどうやって計算して出すか、考えてみてください。

9 10 11 9 11

の平均は10だとわかりますが、それはどう計算したからでしょうか。こんな簡単な数字だとみてすぐフィーリングで解ると思うなら

25.2981 438.21 8372.48

などの数字ならどうやって平均を出すか考えてみてください。
それから、
「小数を扱う事が出来ない数」と「小数点を扱う事が出来ない数」の計算結果は「小数点を扱う事が出来ない数」 でしかありません。
miyazaさんの仰った事を良く見てください。

YYY

Re:たびたび申し訳ありません。

#11

投稿記事 by YYY » 18年前

実行した結果・・・。①ループの中に②のループが入り込んでいました。
②のループは{}で囲まれているため普通に実行。まず①のところに0が代入され、そのあと②が
実行、その後は1とCが同時に出力。
ここまでは分かったんですがその後に0、1、2、Cが出力されるのが分りませんでした。
もう②のループの実行は終わったのでは?

管理人

Re:たびたび申し訳ありません。

#12

投稿記事 by 管理人 » 18年前

 

>実行した結果・・・。①ループの中に②のループが入り込んでいました。

こういうのを2重ループと言います。ループの中にループが入っています。

>ここまでは分かったんですがその後に0、1、2、Cが出力されるのが分りませんでした。

では、言い方を変えてみましょう

for(i=0;i<2;i++){
    ①;
    ②;
    ③;
}

これの実行の順番はもう解りますよね?

①②③①②③

です。では、この②にあたる部分がfor文だとしたら?


for(i=0;i<2;i++){
    ①;
    for(j=0;j<3;j++){
        ②;
    }
    ③;
}

処理はどうなるはずですか?
 

これが解れば、プリントの仕方がわかるはずです。

YYY

Re:たびたび申し訳ありません。

#13

投稿記事 by YYY » 18年前

実行結果はまず0が表示その中に②の結果012が出力次に③が出力その隣に1が出力。
その後再び②③と出力されるって感じでしょうか?仕組みは分かったんですがなぜ1が下に
入力されず隣に行くのでしょうか?これが問題解決のヒントになっているのでしょうか?

YYY

Re:たびたび申し訳ありません。

#14

投稿記事 by YYY » 18年前

ちなみに少数の計算ですが例えばi/jだったらiの前に(float)をつけますね。
そうすれば小数点以下の値も出すことができます。

管理人

Re:たびたび申し訳ありません。

#15

投稿記事 by 管理人 » 18年前

各数字はiの内容なのかjの内容なのかわかりませんが、printf文は\nを書かない限り改行はされません。
これで問題解決になったのではないでしょうか。
処理の順番もこうやって調べてみるとよくわかりますね。
今度はfor文を使うとどのような処理になるかその流れを予測して課題の完成につなげてください。

YYY

Re:たびたび申し訳ありません。

#16

投稿記事 by YYY » 18年前

すみませんね。最初はiの0、次はjの012、次はiの1です。
分りました。改行しなければ横に並ぶんですね。課題はもうあきらめました。
でもfor文が分かったのが収穫ですね。ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る