このページは、練習問題の解答例や解説のページです。
次の2つのコードの意味を説明してください。
if (n > 0) {
std::cout << "OK.\n";
}
while (n > 0) {
std::cout << "OK.\n";
}
1つ目のコードは if文なので、n > 0
という
“条件式が true
になったときに1回だけ”、std::cout << "OK.\n";
を実行します。
2つ目のコードは while文なので、n > 0
という
“条件式が true
になっているあいだ”、std::cout << "OK.\n";
を実行します。変数 n の値を条件式に使っていますが、while文の内側で変数 n
の値を変更していません。そのため、初回の判定で n > 0
が
true
になり、ループの内側に入っていったのならば、それっきりループから抜け出すことはなく、無限ループになっています(本編解説)。
次の while文はどういう意味ですか?
while (0) {
// なんらかの処理
}
while文の条件式が 0
となっています。0
という整数は、bool型に直すと false ですから(「論理値」のページを参照)、この
while文の条件式は「必ず false」です。
したがって、この while文の内側に入ることはなく、「なんらかの処理」が実行されることもありません。
次の for文を、同じ結果になるように while文で書き換えてください。
for (int i = 0; i < 5; ++i) {
std::cout << i << "\n";
}
この for文は典型的な回数指定のループになっていて、5回だけループします(「for文」のページを参照)。周回のたびに、変数 i の値を出力するので、実行結果はこうなります。
0
1
2
3
4
while文で同じことをするのなら、次のように書きます。
#include <iostream>
int main()
{
int i {0};
while (i < 5) {
std::cout << i << "\n";
++i;
}
}
実行結果:
0
1
2
3
4
for文の int i = 0;
の部分は、for文の実行の最初にだけ実行されるものですから、while文であれば、while文に入る直前で実行します。
条件式が確認されるタイミングは for文でも while文でも同じですし、意味も同じなので、ここは特に変える必要はありません。
for文の ++i
は、周回が終わるたびに実行されるものなので、while文なら、内側の処理の末尾で行えばいいです。
これで同じ意味になりますが、変数 i の宣言がループの外に飛び出してしまう点に不満もありますし、for文で書いた方が自然です。
次の for文を、同じ結果になるように do文で書き換えてください。
for (int i = 0; i < 5; ++i) {
std::cout << i << "\n";
}
今度は do文に書き換えます。
#include <iostream>
int main()
{
int i {0};
do {
std::cout << i << "\n";
++i;
} while (i < 5);
}
実行結果:
0
1
2
3
4
for文の int i = 0;
の部分は、for文の実行の最初にだけ実行されるものですから、do文であれば、do文に入る直前で実行します。do文に入ってから行うと、周回のたびに変数を宣言・初期化しなおすことになってしまいます。
条件式が確認されるタイミングが for文と
do文とでは異なります。最大の違いは、ループの初回にチェックされるかどうかで、for文ならチェックされ、do文ならチェックされません。今回の場合、条件式は
i < 5
であり、変数 i の初回の値は 0
であることが分かっているので、初回のチェックの有無は別に問題になりません。そのため、特に条件式を変更する必要はありません。
for文の ++i
は、周回が終わるたびに実行されるものなので、do文なら、内側の処理の末尾で行えばいいです。
これで同じ意味になりますが、もちろん、for文で書いた方が自然です。
この問題では変更する必要がなかったですが、条件式が同じでいいのかどうかはよく考えなければなりません。条件式を変更しなければならないのであれば、そもそも、do文への置き換え自体が不適切な可能性も高いです。特に、do文の内側に入った直後に if文で条件確認するようなコードになるようなら、明らかに do文の使いどころが間違っています(do文は必ず1回以上はループさせるものなので)。
次の do文を、同じ結果になるように、無限ループを使ったかたちに書き換えてください。
#include <iostream>
int main()
{
int value {};
do {
std::cout << "Please enter the integer.\n";
std::cin >> value;
if (value > 0) {
std::cout << value << " is positive number.\n";
}
else if (value < 0) {
std::cout << value << " is negative number.\n";
}
} while (value != 0);
}
整数の入力を受け取り、0 より大きいか、0 より小さいかによってメッセージを出力し、ループを続行します。0 だったときには何も出力せずに終了します。
Please enter the integer.
3 <-- 入力した整数
3 is positive number.
Please enter the integer.
-3 <-- 入力した整数
-3 is negative number.
Please enter the integer.
0 <-- 入力した整数
do文で実現すると、変数 value がループの外側に出てしまうことがやや気になるところです。while文や for文で書くと、変数 value をループの内側に入れられます。
#include <iostream>
int main()
{
while (true) {
std::cout << "Please enter the integer.\n";
int value {};
std::cin >> value;
if (value > 0) {
std::cout << value << " is positive number.\n";
}
else if (value < 0) {
std::cout << value << " is negative number.\n";
}
else {
break;
}
}
}
while文に変更し、条件式を true
にしました。これで必ずループに入りますから、do文の「最低でも1回はループする」という動作をマネできます。あとは、適切なタイミングで
break文を使って脱出すればいいです。
入力された値が 0
のときにはループを抜け、そうでなければ続行しなければなりませんから、value == 0
のときに break文を実行するようにします。value == 0
というのは、value > 0
でも value < 0
でもないときなので、ここでは else
を最後に付け足して実現しています。
末尾に .
、途中にいくつかの空白(’
’)を含んだ文字列があるとして、空白を詰めたものを出力するプログラムを、continue文を使って作成してください。
たとえは、“Hello, New World.” という文字列に対しては、“Hello,NewWorld.” を出力します。
たとえば次のようなプログラムになります。
#include <iostream>
#include <string>
int main()
{
std::string s = "Hello, New World.";
for (int i = 0; true; ++i) {
// 空白文字を飛ばす
if (s[i] == ' ') {
continue;
}
std::cout << s[i];
// ピリオドを見つけたら終了
if (s[i] == '.') {
break;
}
}
std::cout << "\n";
}
実行結果:
Hello,NewWorld.
文字列を構成する文字の内容に応じた処理を書くには、文字列内を1文字ずつ順番に調べていくのが基本です。文字列内の文字は
s[0]
のようなかたちでアクセスできるのでした(「文字列の入力」のページを参照)。
ループの終了条件は、末尾の文字まで処理を終えたときです。今回は末尾に
.
があるという前提になっているので、これを利用すればいいですが、.
自体は出力したいので、ループの「条件式」のところで判定せずに、出力処理を終えてから判定するようにし、break文で抜け出すかたちにします。
空白を詰めるためには、調べた文字が ' '
でなければそのまま出力、' '
だったら出力しないようにすればいいです。出力させないようにするために、continue文を使って、出力処理と、ループの終了確認のコードをスキップさせています。
なお、continue文を使わなくていいのなら、次のようにも書けます。
#include <iostream>
#include <string>
int main()
{
std::string s = "Hello, New World.";
for (int i = 0; true; ++i) {
// 空白文字を飛ばす
if (s[i] != ' ') {
std::cout << s[i];
// ピリオドを見つけたら終了
if (s[i] == '.') {
break;
}
}
}
std::cout << "\n";
}
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |