このページは、練習問題の解答例や解説のページです。
次のプログラムの実行結果はどうなりますか?
#include <iostream>
int main()
{
int value {10};
int value2 {-10};
= value2;
value std::cout << value << "," << value2 << "\n";
= value + 5;
value2 std::cout << value << "," << value2 << "\n";
= value2 = 100;
value std::cout << value << "," << value2 << "\n";
}
最初の代入 value = value2
で、value2 の値が value1
へ代入されます。value2 の値は -10 なので、value の値も -10
になります。代入では右辺の変数の値は変化しませんから(本編解説)、value2
は -10 のままです。
2つ目の代入 value2 = value + 5
では、value の値に 5
を足した結果が、value2 に代入されます。この時点での value の値は -10
になっていますから、-10 + 5
の結果である -5 が value2
に代入されます。value は -10 のままです。
3つ目の代入 value = value2 = 100
は2つの代入式が含まれています。この場合、右側から順番に処理していきます(本編解説)。まず、value2 = 100
によって、value2 の値が 100 に変更されます。次に
value = value2
の部分が処理されて、value の値も 100
に変更されます。
したがって、実行結果は次のようになります。
実行結果:
-10,-10
-10,-5
100,100
次のプログラムにある3つの代入がコンパイルできない理由を説明してください。
#include <iostream>
int main()
{
constexpr auto a = 100;
= 200; // 代入1
a 100 = 200; // 代入2
= 200; // 代入3
b
int b {};
std::cout << a << "\n";
std::cout << b << "\n";
}
「代入1」は、左辺側が constexpr変数であるため代入できません。constexpr変数は、コンパイル時に値が確定しており、実行中に値を変更することはできません。
「代入2」は、左辺側がリテラルであるため代入できません。リテラルは、値そのものであり、変数のように値を入れておく「場所」ではありません。
「代入3」は、左辺側の変数 b が、まだ宣言されていないため代入できません。実行はソースコードの上から下へと進んでいくので、代入よりも後ろで宣言されているのではダメです。
「代入を使ったプログラム」のサンプルプログラムで、変数total を追加して、入力された整数の合計を求めるとき、
int value1 {};
std::cin >> value1;
+= value1; total
というかたちのコードになっています。変数total を std::cin に直接指定しないのはなぜか説明してください。
std::cin は、入力されたデータを指定された変数にそのまま代入するだけですから、直接、変数total を指定すると、そのつど内容が上書きされていくだけであって、合計値が求められるわけではないからです。
入力データはいったん変数に受け取り、それからその変数を使った処理を行うように書かなければなりません。まとめて書くことはできません。
次のプログラムの問題点を指摘してください。
#include <iostream>
int main()
{
int value {10};
int value2 {};
*= 2;
value2 /= value2;
value std::cout << value << "\n";
}
問題はゼロ除算をしていることです(ゼロ除算については、乗算と除算のページを参照)。
まず、value2 の宣言のとき、{}
を指定しているので、型に応じたデフォルト値が初期値になります。int型なら 0
ですから、value2 は 0 で始まります。
value2 *= 2
は value2 = value2 * 2
と同じ意味です。よって、value2 の値が 2倍されますが、元々 0 なので、0
のままです。
value /= value2
は value = value / value2
と同じ意味です。value2 の値は 0 なので、ここでゼロ除算になります。
整数を1つ入力させ、その数を2倍した数、さらに2倍した数、それをさらに2倍した数・・・を順々に出力するプログラムを作成してください(適当なところで止めてください)。
次のように書けます。
#include <iostream>
int main()
{
std::cout << "Please enter the integer.\n";
int value {};
std::cin >> value;
*= 2;
value std::cout << value << "\n";
*= 2;
value std::cout << value << "\n";
*= 2;
value std::cout << value << "\n";
*= 2;
value std::cout << value << "\n";
*= 2;
value std::cout << value << "\n";
}
実行結果:
Please enter the integer.
5 <-- 入力した整数
10
20
40
80
160
複合代入演算子を使って、変数value の値を次々に変更しながら出力を繰り返しています。
2つの int型の変数 a, b があるとして、互いに値を入れ替えるプログラムを書いてください。
変数a の値と変数b の値を入れ替えるには、a = b
と
b = a
が必要であることは明らかです。しかし、代入は、代入先の値を変更してしまう行為ですから、先に
a = b
をすると、変数a の値は変数b
の値に置き換わってしまいますし、逆に b = a
を先にすると、変数b の値が変数a
の値に置き換わってしまいます。つまり、どちらを先にしたとしても、他方に自分の値を渡す前に、他方によって自分の値が書き換えられてしまい、うまくいきません。
#include <iostream>
int main()
{
int a {10};
int b {20};
= b;
a = a;
b
std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
}
実行結果:
a = 20
b = 20
変数の値を入れ替えるには、もう1つ変数を追加する必要があります。そして、他方に自分の値を書き換えられてしまう前に、自分の値を追加した変数に退避しておきます。最後に退避しておいた値を他方にコピーすれば、値の入れ替えが実現できます。
#include <iostream>
int main()
{
int a {10};
int b {20};
int work {};
= a; // a の値を退避
work = b; // b を a にコピー
a = work; // 退避しておいた a の値を b にコピー
b
std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
}
実行結果:
a = 20
b = 10
このような、2つの変数の値を入れ替える処理は、値の交換(swap)と呼ばれ、非常によく登場するプログラムです。
退避用の変数につけた名前 work は、小さめの作業をこなすために使う一時的な変数によく付けられる名前です。ほかに、「temporary: 一時的な」を意味する temp や tmp がよく使われます。
値の交換については、アルゴリズムとデータ構造編【その他】第1章で、より詳しくあつかっています。
問題6のプログラムは、変数の型が std::string であったとしたらどうなりますか?
代入の処理は、int型でも std::string型でも同様に行えますから、値の交換の処理もそのままのかたちで実現できます。当然、値の退避に使う変数 work の型も std::string にする必要があります。
#include <iostream>
#include <string>
int main()
{
std::string a {"abc"};
std::string b {"xyz"};
std::string work {};
= a;
work = b;
a = work;
b
std::cout << "a = " << a << "\n";
std::cout << "b = " << b << "\n";
}
実行結果:
a = xyz
b = abc
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |