![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
プログラミングの勉強をしています。
右上が直角とかるプログラムを作成せよという問題でサンプルコードが次のように書かれていました。
int main(void)
{
int i,j,k;
printf("何段ですか:");
scanf("%d",&i);
for (k=0; k<i; k++) {
for (j=0; j<k; j++) {
printf(' ');
}
for (; j<i; j++) {
printf('*');
}
printf("¥n")
}
return 0;
}
このサンプルコードについて
for(k=0から最後の文まで意味が分からなくて質問させていただきました。
分からない点はk,jが何に対する変数かとそれぞれのforがどういった意味の繰り返しかということです。
分かるかたがいましたら解説をお願い致します。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
それを知るには
for (k=0; k<i; k++) {
の i が何を表わしているのか、を考えましょう。
iは
printf("何段ですか:");
scanf("%d",&i);
で入力した「段数」です。
※ 練習用ということで、 i という単純な変数名を使っていますが、
実践では、意味のある名前を付けるのが、プログラムをわかりやすくするコツです。
例えば: rows,size , dansuu 等
出力した図形は
上から1段目 最上段+0段目: 空白が0個 + *がi個 の計 i 個
上から2段目 最上段+1段目: 空白が1個 + *がi -1個 の計 i 個
...
上からX段目 最上段+(X-1)段目: 空白がX-1個 + *が(i -(X-1))個 の計 i 個
...
上からi段目 最上段+(i-1)段目: 空白がi-1個 + *が1個 の計 i 個
という形になります。
これを
for( 段数分の繰り返し ) {
1談分の出力
}
と繰り返したい場合、いろんなやり方が考えられます。
for( 段数分の繰り返し ) でのループ変数から、他の「上から何段目」「最上段+?段目」「空白の個数」「*の個数」が求められれば、どんな方法でも構いません。
ですが、どうせなら、楽にできるものがいいです。
それぞれを k とすると
「上から何段目」 for( k=1;k<=i;k++)
「最上段+?段目」「空白の個数」 for( k=0;k<i;k++)
「*の個数」 for( k=i;k>=1;k--)
いずれでも、ループ内の計算を変えれば利用できます。
その中で
「最上段+?段目」「空白の個数」 for( k=0;k<i;k++)
を採用したのが、そのプログラムです。
また、C言語でも ループは 0 から始めることが多いです。
配列は 0 から始まります。
ポインタは 基準となるアドレス ±α で使うことが多いです。
このように「基準 + 差分」という処理をする場合には、 差分=0 から始めるのが都合がいいです。
No.3
- 回答日時:
「ループ」「多重ループ」「ループの入れ子構造」はご理解できてますか?
forループは
for(〜) {
ここを繰り返し
}
という形で 「ここを繰り返し」の部分を繰り返します。
この 「ここを繰り返し」の部分には、長くて複雑なプログラムも書けます。
そして、forループも書けます。
このプログラムの場合
for (k=0; k<i; k++) {
}
でループしていて、「ここを繰り返し」の部分が
for (j=0; j<k; j++) {
printf(' ');
}
for (; j<i; j++) {
printf('*');
}
printf("¥n")
となっています。
※ このように、ループの中にループがあるような構造を「多重ループ」「ループの入れ子構造」と呼びます。
for (k=0; k<i; k++) { と変数kを使ってループしているので、
ループを展開すれば
k=0;
for (j=0; j<k; j++) {
printf(' ');
}
for (; j<i; j++) {
printf('*');
}
printf("¥n")
k=1;
「ここを繰り返し」
.....
k=i - 1;
「ここを繰り返し」
/* ループ終了 */
「ここを繰り返し」
の部分を一つ一つ見ていけば
・「空白を出力(改行無し)」をforで繰り返し
・「*を出力(改行無し)」をforで繰り返し
・改行を出力
だとわかります。
これは、「1行分の空白と*と改行の出力」です。
つまり
for (k=0; k<i; k++) {
「1行出力」
}
というのがメインプログラムです。
for (j=0; j<k; j++) {
のループの方はわかるでしょう。
少し高度なのは、
for (; j<i; j++) {
という書き方です。
for文は for(初期化式; 判定式 ; 更新式 ) という形に ; で区切られています。
・初期化式:
ループ開始時に1回だけ実行される。
省略すると、何もしない
・判定式
判定結果が真である限り、ループを続ける。/条件を満さなくなったらループを抜ける。
省略すると、常にループを続ける
・更新式
各ループの終了時に実行する。
省略すると、何もしない
for (j=0; j<k; j++) {
は
j=0 に初期化
0<k でループ継続
ループ終了時に j++ で j=1
1<k でループ継続
ループ終了時に j++ で j=1
...
ループ終了時に j++ で j=k
k<k でないのでループ首領
という動作になるので、forループ終了時には j=k となっています。
その直後に for (; j<i; j++) { があるので、このループは j=k の状態から開始したことになります。
わざわざ書けば for (j=k ; j<i; j++) { です。
丁寧な回答ありがとうございます。
不明な点が少しあるので質問させていただきます。
なぜ最初のループがk=0で始まっているのでしょうか?
kがそもそも何を表しているのでしょうか?
そこが分からないので教えていただきたいです。
No.2
- 回答日時:
とりあえず実行できるようにしてみました:
https://paiza.io/projects/4aaA7XblE2Q4Ky-mhRhbgA
出力結果をみると、主題どおり右上が直角になってます。
この形をつくるために
1) for ( j=0; j<k; j++ ){ printf( " " ); }
2) for ( ; j<i; j++ ){ printf( "*" ); }
3) printf( "\n" );
――を繰り返してますが、k=0のとき、そしてk=1のときに、1)や2)がどういう出力をするかをデバッガでステップ実行させてみてください。そのうえで、k=2やk=3のときの挙動を頭の中でシミュレートできれば、意味を理解したといえると思います。
No.1
- 回答日時:
>分かるかたがいましたら解説をお願い致します。
ソースコードを インデントをつけて書き直して見れば、わかるのでは?
int main(void)
{
int i,j,k;
printf("何段ですか:");
scanf("%d",&i);
for (k=0; k<i; k++) {
for (j=0; j<k; j++) {printf(' ');}
for ( ; j<i; j++) {printf('*');}
printf("¥n");
}
return 0;
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# LU分解法のピボッティングについて(C言語/gcc-9) 3 2022/07/11 23:10
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画面を強制的に再描画させる方法
-
UWSCの終了の仕方
-
VBAでの一時停止と再開の方法
-
DoEventsが必要な理由について
-
乱数の桁数指定、または範囲指定。
-
vb.netからエクセル関数書き込み
-
VBA Boxが空白の場合のメッセー...
-
Java 南京錠
-
vbscriptでIE自動入力(途中で...
-
ループを回すという意味は何で...
-
GIFアニメをループさせたくない
-
Do whileでExitせず、ループの...
-
エクセルの当番表を作っていま...
-
ループ内での条件処理
-
範囲指定したセルを1つずつ飛...
-
WHILE (CHKIMG(”A.bmp”)=FALSE)...
-
モンテカルロ法
-
UWSCに制限時間を付けたいです
-
csh foreachで「*」でエラ...
-
スレッド起動したフォームを正...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
画面を強制的に再描画させる方法
-
VBAでの一時停止と再開の方法
-
UWSCの終了の仕方
-
DoEventsが必要な理由について
-
VBAで3秒だけ時間を止めたい
-
範囲指定したセルを1つずつ飛...
-
Escキーを押すと、中断する時と...
-
DOSコマンドのループ内のTIMEコ...
-
vbscriptでIE自動入力(途中で...
-
乱数の桁数指定、または範囲指定。
-
GIFアニメをループさせたくない
-
プログラミングについて。 1つ...
-
エクセルの当番表を作っていま...
-
テキストボックスの名前に変数...
-
ループフリー
-
vb.netからエクセル関数書き込み
-
CSVファイルの特定の行だけを読...
-
VBA for i=1 to lastrow
-
どなたかこのプログラミングを...
-
Do whileでExitせず、ループの...
おすすめ情報