質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.59%

おそらく簡単つまづいてるのは自分だけ? while文をfor文に

解決済

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 1,676

score 13

int money = 1, month = 1;

    while (money < 1000000) {
        printf("%02d 月目 : %7d 円\n",month,money);
        money *= 2;
        month++;
    }
    printf("%02d 月目 に %d 円となり、100万円を超える。\n",month,money);

 
苦しんで覚えるc言語というサイトでわからないなりに進めていってるんですが
回数が決まっている繰り返しでfor文
回数がわからない繰り返しでwhile文の説明がありました
while文はfor文にも直せるみたいなんですが
このwhile文の例をfor文に直そうと色々やってみたんですが
わからなくて(エラー出たり明らかに間違ってそうだった) これは問題じゃないから答えもないからわからなくてなので教えてください

答え見たら公式?みたいになんとなくわかって似たような問題解けるかもだし
for文にするには初期化と更新の文を省略するだけです。って書いてたけどわからない

言い訳をいっぱいしたのは問題丸投げ批判されるのが怖かったからです

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+3

答えを書いてしまいますと、こうなります。

int money, month = 1;
for(money = 1; money < 1000000; money*=2) {
    printf("%02d 月目 : %7d 円\n",month,money);
    month++;
}


while文からfor文に直す問題をやるより前に、for文とはこう書くんだ、ということを学習していないんですか?
問題を解く以前に基礎がわかっていないと、「苦しんで覚える」という苦しむ意味が違ってしまうと思いますよ。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/28 18:42

    回答ありがとうございます答えがなかったらできなかったです助かりましたありがとうございます
    month=1;とmonth++はfor()の中に入れてはいけないのですね 

    int i;
    for (i = 1;i <= 繰り返し回数;i++) {
    繰り返す文;
    }
    頑張ってを10回繰り返してくださいとか こういうのはこの型を見ながらですができます
    基礎全然なので 基礎も引き続きします ありがとうございます 

    キャンセル

  • 2016/06/28 21:06

    > month=1;とmonth++はfor()の中に入れてはいけないのですね
    いえ、そんなことはありませんよ。
    カンマで区切れば複数かけます。

    for(money = 1, month = 1; money < 1000000; money*=2, month++) {

    書けるけどなんでも詰め込むとわかりづらくなるので私は書きません。
    このループで主体となる(条件となる)変数のみを書くようにしています。
    沢山プログラムを書いていけば自分のスタイルが出来上がっていくと思います。
    色々なコードを参考にしてみてください。

    キャンセル

  • 2016/06/30 01:33

    while文の時
    int money,month=1は表示がおかしかったです
    int money=1,month=1じゃないとダメなんですね
    forの場合はint money,の部分はもうmoney=1にforの中で初期化されてるから書かなくて大丈夫なんですね 
    複数書いてみました 確かにかけました ありがとうございます

    キャンセル

+1

C言語の場合、forwhileは、書き方の違いでしかありません。

/* forでの書き方 */
for(式1; 式2; 式3){
  ループの文;
}

/* whileでの書き方 */1;
while(式2){
  ループの文;
  式3;
}

ここで、forの場合の式1、式2、式3はいずれも省略できますので、for(; 式2; )のようにすれば、whileのときと一致することがわかると思います。

なお、forで式2を省略した場合、条件は真であるとみなされます。そのため、for(;;)while(1)はどちらも無限ループになります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/28 18:42

    回答ありがとうございます 式1式2 式3なんだろうと思ったのですがサイトも見ていると 気づくことができました 初期化 条件式 更新
    きっかけありがとうございます わかりやすかったです

    キャンセル

+1

質問者さまのいう「for文にするには初期化と更新の文を省略するだけです」というのは、以下のような形を指します。

while(money < 1000000) {
}

for(;money < 1000000;){
}

このwhileとforは全くの同じ意味です。初期化文、更新文を省略というのは、これら2つの文は「書かなくても構文エラーではない」ので、省略することが可能です。極論を言うとforは「条件文」すら省略できます。while文とfor文の構成は以下のようになっていることはすでに学習済みですか?

while(/*条件文*/) { // ←構文エラー。whileの条件文は必ず書かなければならない
}

for( /*初期化文*/ ; /*条件文*/ ; /*更新分*/ ) { // ←構文エラーではない。forはそれぞれ省略可
    // breakしないかぎり無限にループする、全てを省略したfor文「for(;;){}」
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 01:32

    初期化;
    while (条件式) {
      繰り返す文;
      更新;
    }

    for (初期化;条件式;更新) {
    繰り返す文;
    }
    無限ループの時だけ初期化と更新を省略できるんですね 他はエラー出ました
    これとか for (i = 1;i <= 10;i++)

    キャンセル

0

whileはbool型引数がtrueである場合、内部に指定された処理を実行する特性があります。
今回、質問者さんの投稿だと「moneyが1000000未満である場合」が真の条件で、それ以外が偽の条件となります。
一方、forに関しては「初期値を定義し、条件を満たすまでループする」という特性があります。
そのため、記述としては今回moneyは1からスタートなので、初期値1からスタートとし、特定の変数に演算処理を加え、条件を満たしていれば終了する、といった内容になります。

for(初期;条件;更新){
    ここに処理
}


whileの場合だと

while( 条件 ){
  ここに処理
}


あとは質問者さんの本文に答えはありますので、その点は考えてみてください。

余談

めちゃくちゃ細かいことですが、

while (money < 1000000) {


printf("%02d 月目 に %d 円となり、100万円を超える。\n",month,money);


ここで少し内容が食い違っていると思います。
必要なことではないと思いますが、気になりました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 01:32

    http://9cguide.appspot.com/10-01.html この例を使ったのですが間違ってるのですか
    あと最後のprintf("%02d 月目 に %7d 円となり、100万円を超える。\n",month,money);
    の部分はmoney<1000000なのに1048576円になって月も増えているのはmoney=money*2だからmoney*2のmoneyが1000000より小さかったらいいということ?そう考えた時その前の
    printf("%02d 月目 : %7d 円\n",month,money);
    money *= 2;
    month++;
    では20日524288で止まってて最後のprint文を付け加えないとmoney=money*2のmoney*2のところのmoneyが1000000寄り小さい時のmoney(1048576)=money(524288)*2
    21日 1048576が表示されないのは何でだろうと思うし
    money=money*2の money= のmoneyが1000000より小さい時の場合
    20日 524288で繰り返しが終わるのは理解できるのですが
    最後のprint文が何で日付もお金も更新されるのかがわかりません
    print文を書いた回数だけ更新されるのかなと思って最後のprint文プラスもう一つprint文を書いてみたけど更新されないし何でだろうと思いました ぐちゃぐちゃのまとまってない汚い文ですが わからないことを言葉にして頑張って書いてみました このわからないはほうっておいていいんでしょうか わかってないと後々困る 重大な基礎的な考え?なのでしょうか

    キャンセル

  • 2016/06/30 10:20 編集

    例題確認しました。

    ------------------------------------------------------------------------
    ある小学生が、親に頼みました。
    「今月は1円、来月は2円、再来月は4円と、
    先月の倍額のおこずかいをちょうだい」
    さて、親が払う金額が100万円を超えるのは何ヶ月目でしょうか?
    ------------------------------------------------------------------------

    上記の文章だと、組まれたプログラムは誤りです。
    今回のケースだと絶対にありえない(100万ジャストになることはない)ので、
    気にする必要性はこの場合はありませんが、
    正しく組むのであれば、提示されましたURLのサンプルは間違っています。
    ※このあたりはプログラマとして凄い気になる些細な問題です。
    ※100万ジャストの場合、「x月目 に 1000000円となり、100万円を超える。」という文章になるのがおかしい、という指摘です。今回のケースでは絶対的にありえませんが、言葉としておかしいし、実装内容とそぐわないね、というかんじです(大学のプログラミング講習だと、こういった部分をたまに見る教授もいます)

    >20日524288で止まってて
    はい、後ろにも表示のprintをおかないと表示されません。
    これは
    while内ではprint表示したのちに演算処理を行っているからです。

    >最後のprint文が何で日付もお金も更新されるのかがわかりません
    print後に計算しているからです。
    今回のソースを日本語に直しますと

    1. moneyとmonthを初期値1として定義
    2. 1月目に1円 ←ここからwhile
    3. moneyを2倍する
    4. monthを+1する。
    5. moneyが1000000を超える場合6へ、そうでない場合は2へ
    6. n月目にm円となり、1000000を超える

    上記のようになります。
    print文はただの文字の出力です。

    >printf("%02d 月目 に %7.0f 円となり、100万円を超える。\n",month,money);
    この後ろに
    >money *=2;
    >month++;
    を追加し、その後ろにさらに
    >printf("%02d 月目 に %7.0f 円。\n",month,money);
    と記載すれば、からくりはわかると思います。

    キャンセル

  • 2016/06/30 16:53 編集

    moneyはmoney*2のmoneyではなくてmoney=のmoneyで 100万を超えても
    最後のprint文は更新できて 更新の後(下)に書かれたprint文は上の更新をできる
    1. moneyとmonthを初期値1として定義
    2. 1月目に1円 ←ここからwhile
    3. moneyを2倍する
    4. monthを+1する。
    5. moneyが1000000を超える場合6へ、そうでない場合は2へ
    print文1はmoney=のmoneyが1000000以下の最大の数値となった時まで繰り返される
    print文1はwhile文なので更新が下にあってもmoney monthの値が変わることができる?
    6. n月目にm円となり、1000000を超える 
    print文2は直前(真上)の更新を実行する これが普通print文は上に更新がないと変わらない
    上から順番に実行 下から上はできない ?
    であってるでしょうか
    こんなことでつまづいてるとこれだけに何時間使ってるんだと先が思いやられます 向いてないですよね 次々にわからないことが出てきて 7割くらい理解できたらいいのかな
    ここのサイトに質問してないわからないことっていっぱいあってでも いざ質問するのと回答に返信するのと考えるのとですごく時間経って結局なんにもほとんど進まないという
    プログラミングに限らず普通の学習でもこうなんですがわからないことを放っておいて先に進んだほうがいいとは思うんですが わからないことを許してもいいですよね

    だいぶ話が逸れました 愚痴部分はスルーしてください 独り言のように余計なことが書き出したら止まらなくて ありがとうございます

     

    キャンセル

0

for 文の基本形は次のようなものです。

int i;
for (i = 0; i < 100; i++)
{
    //ループする内容
}


最初のi=0は初期化です。
ループが始まる前に変数 i に 0 を代入しています。

次のi < 100は継続条件です。
ループの先頭で評価して、これが真でない場合、ループを終了します。

最後のi++はループ毎に行う処理です。

以上を while で表すと、次のようになります。

int i = 0;
while (i < 100)
{
    //ループする内容
    i++;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 01:34

    コメントありがとうございます

    キャンセル

0

forとwhileは本質的には同じもので、少しforの方が一度に書けることが多い、というだけです。
forの方が書けることが多いと言っても、forの中に書く式は省略できますので、

while(1){
 ~~~
}


for(;;){
 ~~~
}


は全く同じ意味になります(実際全く同じようにコンパイルされます)。
ループなのでどちらも条件式を書けますが、条件式のみ書けるのがwhile、条件式に加え初期処理と更新処理も一度に書けるのがforというだけです。
まあ、もし分かりにくければ、とりあえずwhile(1)やfor(;;)というように無限ループにしてしまって、if文で条件式を中に書いてbreak;するというのもアリかもしれません(効率は悪いですが、理解はしやすいと思います)。
以下のような感じで。

int i=0;
while(1){
 if(i<100){
  break;
 }
 i++;
}
int i=0;
for(;;){
 if(i<100){
  break;
 }
 i++;
}


とりあえずこういうやり方でループに慣れたら、forやwhileのありがたみが分かると思うので、そうなったらもう大丈夫でしょう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/30 01:34

    コメントありがとうございます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る