Time Limit: 0 msec / Memory Limit: 0 KB
補足
この説明を読む前に付録4.ループの裏技repマクロを読んだほうが理解しやすいです。ただし、必須の知識では無いので読まなくても問題ありません。
キーポイント
- while文を使うと繰り返し処理ができる
- 条件式が真のとき処理を繰り返す
while (条件式) { 処理 }
- 「N回処理する」というプログラムを書く場合、「カウンタ変数を0からはじめ、カウンタ変数がNより小さいときにループ」という形式で書く
int i = 0; // カウンタ変数 while (i < N) { 処理 i++; }
while文
while文を使うと、プログラムの機能の中でも非常に重要な「繰り返し処理」(ループ処理)を行うことができます。
無限ループ
次のプログラムは、「"Hello"
と出力して改行した後、"AtCoder"
と出力する処理」を無限に繰り返すプログラムです。
#include <bits/stdc++.h> using namespace std; int main() { while (true) { cout << "Hello" << endl; cout << "AtCoder" << endl; } }
実行結果
Hello AtCoder Hello AtCoder Hello AtCoder Hello AtCoder Hello AtCoder ...(無限に続く)
while文は次のように書き、条件式が真のとき処理を繰り返し続けます。
while (条件式) { 処理 }
先のプログラムでは条件式の部分にtrue
と書いているため、無限に処理を繰り返し続けます。
このように、無限に繰り返し続けることを無限ループと言います。
1ずつカウントする
次プログラムは、1から順に整数を出力し続けます。
#include <bits/stdc++.h> using namespace std; int main() { int i = 1; while (true) { cout << i << endl; i++; //ループのたびに1増やす } }
実行結果
1 2 3 4 5 6 7 8 ...(無限に1ずつ増えていく)
途中で負の値になったかもしれませんが、なぜそうなるかは3.01.数値型で説明します。
ループ回数の指定
1ずつカウントするプログラムを「1から5までの数を出力するプログラム」に変える場合、次のようにします。
#include <bits/stdc++.h> using namespace std; int main() { int i = 1; // iが5以下の間だけループ while (i <= 5) { cout << i << endl; i++; } }
実行結果
1 2 3 4 5
カウンタ変数は0からN未満まで
5回Hello
と出力するプログラムを考えます。
まず一般的でない書き方(やめておいた方が良い書き方)を紹介し、次に一般的な書き方(推奨される書き方)を紹介します。
一般的でない書き方
#include <bits/stdc++.h> using namespace std; int main() { // iを1からはじめる int i = 1; // iが5以下の間ループ while (i <= 5) { cout << "Hello" << endl; i++; } }
実行結果
Hello Hello Hello Hello Hello
「N回処理をする」というプログラムをwhile文で書く場合、今までは「i
を1からはじめ、N以下の間ループする」という形式で書いてきました。
int i = 1; while (i <= N) { 処理 i++; }
この形式は一見わかりやすいと感じるかもしれません。
しかし、この書き方はあまり一般的ではなく、次のように書いたほうが良いです。
一般的な書き方
#include <bits/stdc++.h> using namespace std; int main() { // iを0からはじめる int i = 0; // iが5未満の間ループ while (i < 5) { cout << "Hello" << endl; i++; } }
実行結果
Hello Hello Hello Hello Hello
「N回処理する」というプログラムを書く場合、次のように「i
を0からはじめ、i
がNより小さいときにループする」という形式で書くのが一般的です。
int i = 0; while (i < N) { 処理 i++; }
最初は分かりづらく感じるかもしれませんが、こう書いた方がプログラムをシンプルに書けることが後々増えてくるので、慣れるようにしましょう。
なお、このプログラムの変数i
のように、「何度目のループか」を管理する変数のことをカウンタ変数と呼ぶことがあります。
カウンタ変数は基本的にi
を使い、i
が使えない場合はj
, k
, l
...と名前をつけていくのが一般的です。
応用例
N人の合計点を求めるプログラムを作ってみましょう。
次のプログラムは「入力の個数N」と「点数を表すN個の整数」を入力で受け取り、点数の合計を出力します。
#include <bits/stdc++.h> using namespace std; int main() { int N; cin >> N; int sum = 0; // 合計点を表す変数 int x; // 入力を受け取る変数 int i = 0; // カウンタ変数 while (i < N) { cin >> x; sum += x; i++; } cout << sum << endl; }
入力
3 1 10 100
実行結果
111
合計点を表す変数sum
を作っておき、ループするたびに入力を変数x
に入れ、sum
に足しています。
このプログラムが実行される様子を表したのが次のスライドです。
このように、繰り返し処理を使えば様々な処理が行えるようになります。
ループ構文を使って様々な処理を書く方法は2.01.ループの書き方や2.02.多重ループで詳しく説明します。
細かい話
細かい話なので、飛ばして問題を解いても良いです。
2ずつ増やす
今まではi
を1ずつだけ増やしてきましたが、2ずつ増やすこともできます。
#include <bits/stdc++.h> using namespace std; int main() { int i = 0; while (i < 10) { cout << i << endl; i += 2; } }
実行結果
0 2 4 6 8
次のように書くことで2ずつ増やしています。
i += 2;
同様にして、より多く飛ばしてループすることもできます。
逆順ループ
5から0までの数を出力したい場合は以下のようにします。
#include <bits/stdc++.h> using namespace std; int main() { int i = 5; while (i >= 0) { cout << i << endl; i--; } }
実行結果
5 4 3 2 1 0
こちらはデクリメントを使うことで1ずつ減らしています。
i--;
無限ループをコードテストで実行した場合
AtCoderのコードテストでは実行時間が長すぎるとプログラムが中断されます。また、出力が長すぎる場合も途中から省略されます。
そのため、はじめに紹介した「"Hello"
と出力して改行した後、"AtCoder"
と出力する処理」を無限に繰り返すプログラムをコードテストで実行しても無限には出力されず、次のように表示されます。
標準出力
Hello AtCoder (中略) Hello AtCoder He...
終了コード
9
無限ループが発生した場合、終了コードは実行時間が長すぎることを表す9
となります。
問題
リンク先の問題を解いてください。