• ベストアンサー

C言語 for文を使った一例について

#include<stdio.h> main () { int i ; int j ; for(i = 0 ; i<5 ; i++){ /*行数の制御部*/ for(j = 0; j<(i+1) ; j++){ /* *の制御部*/ printf("*"); } printf("\n"); } return; } このプログラムを実行すると * ** *** **** ***** が表示されます。 for(j = 0; j<(i+1) ; j++){ ↑    printf("*");} ↑ 「*」の制御部となりますが、 何故「*」が1行目で1個表示されているのに 2行目では2個表示されているのですか? 行数と「*」は同じになると思われますが。 上記の質問の回答の程宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.5

iのforをfor(i)、jのforをfor(j)を表記して、各変数がどのように変移するかを書けば i i+1 j j<i+1 処理 --------------------------- 0 1 0 true *を表示 0 1 1 false for(j)を抜ける(そして改行) for(i)でiを++する。 1 2 0 true *を表示 1 2 1 true *を表示 1 2 2 false for(j)を抜ける(そして改行) for(i)でiを++する。 2 3 0 true *を表示 2 3 1 true *を表示 2 3 2 true *を表示 2 3 3 false for(j)を抜ける(そして改行) for(i)でiを++する。   ・   ・   ・ となり、*の数がどんどん増えることになります。

KGM
質問者

補足

わかりやすい説明で、ほぼ理解することができました。 i i+1 j j<i+1 処理 --------------------------- 0 1 0 true *を表示 ←(1) 0 1 1 false for(j)を抜ける(そして改行) for(i)でiを++する。 1 2 0 true *を表示 ←(2) 1 2 1 true *を表示 1 2 2 false for(j)を抜ける(そして改行)   ・   ・   ・ わからない点があるのですが、←矢印で 示している部分になります。 (1)では、初期値がi=0 , j=0なので *は一つだけ表示されるのはわかります。 (2)で、「1 2 0 true *を表示」の部分において j=0となっていますが、「0 1 1 false for(j)を抜ける」になるとjはインクリメントされ、 初期値が j=1となり、j=0にはならなく、*が表示されないと 思われます。 何故「0」があるのかを教えて頂けませんか。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (14)

  • rentahero
  • ベストアンサー率53% (182/342)
回答No.15

while文はわかりますか? forを使った以下のような構文は、 for(A;B;C) { D; } whileを使って以下のように書き換えられます。 A; while(B) { D; C; } A,B,C,Dの処理の位置に注目してください。 これで元の for(i = 0 ; i<5 ; i++){ /*行数の制御部*/ for(j = 0; j<(i+1) ; j++){ /* *の制御部*/ printf("*"); } printf("\n"); } をかきかえてみると i=0; while(i<5) { j = 0; while( j<(i+1)) { printf("*"); j++; } i++; } となります。 もうわかりましたね。 jの初期化j=0;は、 iのループの中でかつjのループの外にあるから、です。 iのループを回るたびにjは0になるわけです。

KGM
質問者

お礼

書き込みありがとうございます。 非常に助かりました!!

全文を見る
すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.14

ちなみに質問者さんの考えている動作をするプログラムは #include <stdio.h> main () { int i ; int j ; j = 0; /*一回だけ初期化*/ for(i = 0 ; i<5 ; i++){ /*行数の制御部*/ for(; j<(i+1) ; j++){ /* *の制御部 初期化部分がない*/ printf("*"); } printf("\n"); } return; } こうなります。

全文を見る
すると、全ての回答が全文表示されます。
回答No.13

こんにちは、AEと申します。 文法的なことは皆さんが回答されていますので。 なるべく簡単に(^-^)。 > このようなフローがあると思われます。 > j=0の過程がどうしても導きだせません。 多重ループの場合、内側のループは最初から実行されることになります。ここの理解がキモでしょう。 「 for(j = 0; j<(i+1) ; j++) 」  の意味は 「jを0から、 (i + 1)まで、 1ずつ増加させる」   j=0;   j < (i + 1);   j ++; ということですので、jは0に始まり(i+1)未満でループから抜けます。 この処理が最初から行われるということは、j=0からカウントアップが開始されるわけで、結果として、iが5になるまで、jのループ内で(i+1)個の*が横方向に表示されるということになります。 printf()で、iやjの値がどう変化していっているか表示してみるとよいでしょう。理解しやすくなりますよ。 ただ、少し厳しくかつ偉そうに言ってしまいますが、 ○for()文の文法を理解する。 ○多重ループにおけるfor()文のアルゴリズムを正しく理解する。 ということも頑張りましょう! ※今ちょうど一生懸命勉強してはるとこですよね!:)。

KGM
質問者

お礼

言語をやるのは初めてで、さっぱりわからない状態です。。。 ですが、これから着実に進めていきたいと思いますので、 今後とも宜しくお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • Trick--o--
  • ベストアンサー率20% (413/2034)
回答No.12

for(i=0; i<n ; i++){ /* 処理 */ } は次のように書き換えられます i=0; while(i<n){ /* 処理 */ i++; } 質問の場合は for(i = 0 ; i<5 ; i++){ /*行数の制御部*/ for(j = 0; j<(i+1) ; j++){ /* *の制御部*/ printf("*"); } printf("\n"); } なので i = 0; while( i < 5 ) { /*行数の制御部*/  j = 0;  while( j < (i+1) ) { /* *の制御部*/   printf("*"); /* ここでは改行しない */   j++;  }  printf("\n"); /* ここで改行 */  i++; } です。 「初期化」や「インクリメント(++のこと)」、「printfの出力」がどのような順番で実行されているか、確認してください。

KGM
質問者

お礼

非常にわかりやすかったです^^ これで、完全に解決することができました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.11

>2回目のループ開始(i=1) >↓ >i(1)<5→jループに移る >↓ >j=0 //一回目のループでj++されたからj=1になるのでは? >↓ forの処理は、 (1) for文の2番目の式(制御式)がfalseになったとき(2) returnまたはgotoでfor処理の外へジャンプした (3) breakでfor処理を抜けた いずれの場合も終了(完了)します。 だから再度、同じfor文を実行してもそれは継続ではなく新規になります。

全文を見る
すると、全ての回答が全文表示されます。
  • gimmick
  • ベストアンサー率49% (134/270)
回答No.10

>j=0の過程がどうしても導きだせません。 for文で指定する初期化文は、そのfor文を実行する前に1回だけ処理されます。 つまり、質問文の二重ループは次の処理と同等です。 for(i = 0 ; i<5 ; i++){  j = 0;  for(; j<(i+1) ; j++){   printf("*");  }  printf("\n"); }

KGM
質問者

お礼

返信が遅れました。 みなさまの書き込みのお陰で、ようやく理解できました。 最初は、書き方を工夫して慣らしていこうと思います。

全文を見る
すると、全ての回答が全文表示されます。
回答No.9

まず、for() の基本として、 for(<1> ; <2> ; <3>} {.... } は、 ・繰り返しに入る前に<1>を実行 ・<2> の条件が満たされている限り.... を繰り返す ・繰り返しが終わる度に、<3> を実行 はOKですね。 この場合、 for(i = 0 ; i<5 ; i++){ /*行数の制御部*/ for(j = 0; j<(i+1) ; j++){ /* *の制御部*/ というループは、併置されているわけではなく、「外側のループ」「内側のループ」になります。 外側の for(i = 0; ... ) によって、ある処理が5回実行されます。外側のループ自体は、1度しか通過しません(その1度のループの中で、「ある処理」が5回実行されるわけです) ですから、i = 0 という初期化は、1度しか起こりません。 5回実行される「ある処理」とは、実は、for(j = 0...)というループです。 これは、5回実行されます(それぞれの実行中で、* の印字は、i + 1 回実行されます) つまり、j = 0 という初期化は5回実行されます。 このように、i は、1度しか初期化されず、j が5回初期化されるのは、i のループと j のループが、同じものではなく、j のループは、i の「中身」だからです。 ということになるのですが。 ↓ > i(1)<5→jループに移る > j=0 //一回目のループでj++されたからj=1になるのでは? j の初期化は、「j のループが開始された」時に発生します。故に、「jループに移る」時には、必ず実行され、j は0になります。 これに対して、「i ループに『移る』」という箇所はありません(実際には、最初に一回ある) だから、i は、初期化されないのです。 i は、「繰り返しのみ」 j は、「繰り返し(このときは初期化されない)」と「移る(このときは初期化される)と違いがあります。

全文を見る
すると、全ての回答が全文表示されます。
回答No.8

>何故、jが最初に初期化されるのですか。 >それは、iでは起きないのですか >for(j = 0; j<(i+1) ; j++){ /* *の制御部*/ >printf("*"); >} for文は、本来3行以上必要な処理を1行にまとめて書かれています。 つまり、 loop_start: j = 0; loop_check: if (j<(i+j)) goto loop_end  { loop内の処理   printf("*");  } loop_next: j++; goto loop_check loop_end: と、これだけの処理がfor文の中にあるのです。 jを初期化するloop_start:はfor文に入ったときに1度だけ実行され forが継続している間は実行されません。

KGM
質問者

補足

丁寧な書き込みをしていただき、感謝感激です。 ただ、どうしてもjの値がインクリメントされても 「0」になる理由がのみこめません。 1回目のループ開始(i=0) ↓ i(0)<5→jループに移る ↓ j=0 ↓ j(0)<(1):*を表示→j++ ↓ j(1)<(1):条件終了。jループを抜ける ↓ i<5:\n(改行)を表示→i++→1回目のループを抜ける ↓ 2回目のループ開始(i=1) ↓ i(1)<5→jループに移る ↓ j=0 //一回目のループでj++されたからj=1になるのでは? ↓ j(0)<(2):*を表示→j++ ↓ j(1)<(2):*を表示→j++ ↓ j(2)<(2):*条件終了。jループを抜ける ↓ i<5:\n(改行)を表示→i++→2回目のループを抜ける ↓ 3回目のループ(i=2) このようなフローがあると思われます。 j=0の過程がどうしても導きだせません。

全文を見る
すると、全ての回答が全文表示されます。
  • edomin
  • ベストアンサー率32% (327/1003)
回答No.7

「(2)で、「1 2 0 true *を表示」の部分においてj=0となっていますが、「0 1 1 false for(j)を抜ける」になるとjはインクリメントされ、 初期値がj=1となり、j=0にはならなく、*が表示されないと思われます。 何故「0」があるのかを教えて頂けませんか。」 forループの条件で最初に「j=0」を与えているからです。 for文を抜けた直後の「j」は「1」ですが、「i」のループによって再度forループに突入します。その際、最初に初期化されるので、質問のプログラムだとj=0から始まることになります。

KGM
質問者

補足

何故、jが最初に初期化されるのですか。 それは、iでは起きないのですか。 i=0 i=0の条件でループが始まる ↓ i=0 J=0の条件でループが終了 ↓ i++ j++される(i=1 J=1) ↓ i=1 J=1の条件でループ開始 このような過程の中で、jがどう初期化されるのかを 教えて下さい。宜しくお願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • gimmick
  • ベストアンサー率49% (134/270)
回答No.6

二重ループの部分を(A)とします。(説明を短くするため、外側のループの5は3に変えます。) ----(A)--------------------------------- for(i = 0 ; i < 3 ; i++){  for(j = 0; j < (i + 1); j++){   printf("*");  }  printf("\n"); } ---------------------------------------- (A)の外側のforループを展開します。これを(B)とします。 ----(B)--------------------------------- for(j = 0; j < 1; j++){  printf("*"); } printf("\n"); for(j = 0; j < 2; j++){  printf("*"); } printf("\n"); for(j = 0; j < 3; j++){  printf("*"); } printf("\n"); ---------------------------------------- (B)のforループを全て展開します。これを(C)とします。 ----(C)--------------------------------- printf("*"); printf("\n"); printf("*"); printf("*"); printf("\n"); printf("*"); printf("*"); printf("*"); printf("\n"); ---------------------------------------- というわけで、(A)の処理は(C)の処理と同じ働きをします。 (マシン語レベルで同一とは言えませんが。) 不明な点があったら補足してください。

KGM
質問者

補足

書き込みありがとうございます。 今、for文のメカニズムがわからない状態です。 i , j の中に入る数字で、「jが初期化される」と いうことがさっぱりわからないのです。 その点について、詳しく教えて頂けたらと思っています。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語について

    C言語の問題なのですか、作成したのですが内容がわからないです。テキストを読んでも解説が書いていないので、出来ればどなたか簡単な解説でも教えて頂けるとありがたい。 〈7-3〉 #include <stdio.h> int main(void) { int i, j; long kuku[9][9]; // 九九の値の代入処理を記述 for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { kuku[i][j] = (i + 1) * (j + 1); } } ///////////////////////////////////// // 九九の表示部(ここは変更しないこと) for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { printf(" %2d", kuku[i][j]); } printf("\n"); } return 0; }

  • for 3ループについて教えて

    for 3ループについて教えて * ** *** **** * ** *** **** * ** *** **** と表示させたいのですが、 #include<stdio.h> int main(void) { int i,j,k; for(i=1; i<=4; i++) { for(j=1; j<=i; j++){ // for(k=1; k<=3; k+=i){ } printf("*"); } printf("\n"); } return 0; } * ** *** **** このように表示されてしまいます。//の所が違うなと思います。が、分かりそうで分かりません。 もし、分かるかたがいましたら、教えてください。 よろしくおねがいします。

  • C言語で困っています...

    入力した数値の列だけ○と×を縦に、段々になるように表示する (最後の行は×にならなければいけない)プログラムを作成しています。 (実行例) ○と×を表示します。何列?:10            ×           ○×          ×○×         ○×○×         ×○×○×       ○×○×○×      ×○×○×○×    ○×○×○×○× ×○×○×○×○× ○×○×○×○×○× 途中までプログラミングできたのですが、 偶数の数値を入れたときはきちんと最後の行は×になっても 奇数の数値を入力すると○が最後の行になってしまい、うまくいきません。 どこがだめなのでしょうか? どなたか教えてください。 /* 入力した数値の列だけ、○と×を縦に、   段々になるように表示する(最後の行は×になる) */ #include <stdio.h> int main(void) { int i, j, n; printf("○と×を表示します。何列?:"); scanf("%d", &n); for (i=0; i<n; i++){ for (j=0; j<n; j++){ if (j >= (n - 1) - i){ if (j % 2 == 0) printf("○"); else printf("×"); } else printf(" ");//全角スペース } printf("\n"); } return 0; }

  • C言語の2次配列

    4行5列の配列を用意し、その配列の要素をtij(i=1~4, j=1~5)とするとき、tij=i×j となるように配列に値を入れ、 それを表の形で画面に表示するプログラムを作りなさい。  という問題なんですが、自分は下の様に組みましたがうまく動きません。どこが悪いのか教えてください。よろしくお願いします。あまりC言語を理解していないので申し訳ないですが、なるべく簡単に教えて頂ければ幸いです。 #include<stdio.h> int main(void) { int i,j; int t[4][5]; for(i=0;i<=3;i++) { for(j=0;j<=4;j++) t=i*j; printf("%5d",t); printf("\n"); } return 0; }

  • C言語  九九表

    九九表を作ろうとしたのですが、うまくいきません、解説お願いします。 #include<stdio.h> main() { int i ; int j ; for( i=1 ; i<=10 ; i++){ for( j = 1 ; j<=10 ; j++) { printf("%4d\n") , i*j ; } printf("\n") ; } } 結果 10 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832 -748408832     が10個続いてました・・・・

  • C言語の問題です!!

    C言語の問題です。次の問題でプログラムを作ってみたのですがどうでしょうか?もし小さな間違いであったら訂正をお願いします。全然違う場合はそのように回答してください。初心者なものでよろしくお願いします。 ・1~100までの整数値を画面に表示せよ. ただし,数値を10個表示するごとに改行すること. #include<stdio.h> int main(void){ int i,j; for(i=1;i<=100;i++){    for(j=1;j<=9;j++) printf("%3d",i+j); i=i+9; putchar("\n"); } return(0); }

  • for文

    整数を読み込んで、その値を0までカウントダウンしながら表示するプログラム作りたいのですが、 while文ではできたのですが、for文ではうまくいきません。 どこが間違っているのでしょうか? OS:Windows XP C++Builder X パーソナル #include <stdio.h> int main(void) { int i; int num; printf("整数を入力してください:"); scanf("%d", &num); for(i = num; i <= 0; --i) { printf("%d", i); } return 0; } 宜しくお願いします。

  • C言語のwhile文はネストできますか?

    「*」を使用して、n列、m行の四角を表示させるプログラムを考えました。 --------------------------------------------------------------------------------------------- #include<stdio.h> int main(void) { int i=0,j=0,n,m; printf("n入力:"); scanf("%d",&n); printf("\nm入力:"); scanf("%d",&m); printf("\n"); while(i<m){ while(j<n){ printf("*"); j++; } printf("\n"); i++; } return 0; } --------------------------------------------------------------------------------------------- しかし、1行分しか表示されません。 n=2、m=2の場合 ----------------- n入力: m入力: ** ----------------- としか表示されません。 whileのネストが悪いのでしょうか? それとも、初歩的なミスがあるのでしょうか?

  • C言語プログラミングで・・・

    つい最近、C言語プログラミングのお勉強をはじめた中学生です。 ある程度かけるようになってきて、こちらのサイトに掲載されている練習問題を解いていました。 http://akabas.net/lib/CExercise.aspx いろいろといていく中で、配列の章にはいりました。 配列の章の中の6問目と7問目の九九についてのコードを書いていたところ、どちらも問題なく実行を終了した後 「○○.exeは動作を停止しました。」というメッセージが現れました。 これはコードに何か問題があるのでしょうか? _____________________________________________________________________ //6問目 #include <stdio.h> void line (void){ int cnt; for (cnt = 0; cnt < 30; cnt++) printf("_"); printf("\n"); } int main() { int kuku[9][9], i, j; printf("九九を表示します\n"); for (i = 1; i <= 9; i++){ for (j = 1; j <= 9; j++){ kuku[i][j] = i * j; printf("%d * %d = %d\n", i, j, kuku[i][j]); } line(); } return 0; } ____________________________________________________________________ //7問目 #include <stdio.h> int main() { int kuku[9][9]; int i, j; for (i = 1; i <= 9; i++){ for (j = 1; j <= 9; j++) kuku[i][j] = i * j; } printf("1桁の数値(1 ~ 9に限定)を入力してください 1回目---"); scanf("%d", &i); printf("1桁の数値(1 ~ 9に限定)を入力してください 2回目---"); scanf("%d", &j); printf("\n"); printf("%d * %d = %d", i, j, kuku[i][j]); return 0; } ________________________________________________________________________________ まだ初心者のレベルなので、回答はできたらきつい言葉をつかってほしくないです^^; よろしくおねがいします ※こちらでは、Tabをうっているのですが、表示されてないみたいです。見づらいかと思いますが、よろしくおねがいします

  •  現在、私はC言語を学んでいます。

     現在、私はC言語を学んでいます。  プログラミングの初期の初期の問題なんですが、 「Hello World」という有名なプログラムがありますよね? それについての質問です。 #include<stdio.h> main() { printf("Hello World"); return 0; } も #include<stdio.h> main(void) { printf("Hello World"); return 0; } も #include<stdio.h> int main() { printf("Hello World"); } もちゃんと表示できます。 ここで質問です。 int main(void) int main() main() main(void) はどう違うんですか? あと、 return 0; はあっても無くてもいいようなんですが どういう意味があるんでしょうか?