要約
このレッスンは、式とその演算子を扱うコースの第三単元を締めくくる。算術演算子からライブラリ関数に至る概念の連鎖を、式の木と各ノードの型、条件とその代数、短絡評価、副作用と評価順序、ビットを経由して組み立て直す。そのうちどの言語でも通用することを C++ に固有のことから分ける。単元の未定義動作を、コンパイラが検出するもの、サニタイザが検出するもの、誰も検出しないものとともにまとめる。まとめテストで導入テストの技能を繰り返す。そして単元全体を組み合わせた六つの挑戦課題で終わる。
学習目標
- コースに出てくるどの式についても、その木と各ノードでの変換から、値、型、作用を予測する。
- 複合条件を書き、否定し、短絡評価を使って、そうしなければ意味を失う演算を守る。
- 意味をもたない式(単元の未定義動作の一覧)を見分け、それぞれを検出する道具を挙げ、未定義動作のない形に書き直す。
- 与えられた計算について、算術、ビット演算子、数学ライブラリのいずれを使うかを選び、その選択の理由を述べる。
- 単元で学んだことのうち、どの言語でも通用することと C++ に固有のことを分ける。
単元で達成したこと
この単元は、値を確実に予測できる式の組み立て方を教えようとした。どの演算が先に行われるか、結果はどの型か、どんな副作用があるか、どの式が意味をもたないか、である。その目的は、導入が既知とした事柄、すなわち第 2 単元の型、その値の範囲、その変換だけに頼って達成された。導入が問題を提起したときの六つの問いのプログラムは、今ではコンパイラが読むように読むことができ、式ごとに修正できる。
算術演算
レッスン 算術演算 は、五つの算術演算子の正確な振る舞いを定めた。整数除算は 0 方向に切り捨て、商が意味をもつかぎり等式 (a / b) * b + a % b == a を満たす。したがって剰余は、0 でないときは被除数の符号をもつ。そのため -7 / 2 は 、-7 % 2 は であり、奇数かどうかは n % 2 != 0 で問う。このレッスンはこれをユークリッドの剰余 ((a % b) + b) % b( の場合)と結びつけ、両方を使って量を分解した。優先順位と結合規則に従って式の木を描き、通常の算術変換によって各ノードの型を決めることを教えた。最後に、意味をもたない商(0 による整数除算と、最小の整数を で割ること)と、途中結果のオーバーフローを扱った。途中結果のオーバーフローは、最終結果が収まっても未定義動作になるのに十分である。
関係と論理
レッスン 関係と論理 は、条件が bool 型の式であり、木のなかに場所をもつことを教えた。関係演算子は算術より結びつきが弱く、&& は || より強く、! はそのどれよりも強い。文章を条件に翻訳すること、そして 1 < x < 5 や day == 6 || 7 のように、別の意味でコンパイルされてしまう条件を見分けることを教えた。&& と || は、第一オペランドで結果が決まらないときにだけ第二オペランドを計算すること、そしてこの短絡によって、演算をその左に置いた見張りで守れることを示した。最後に、複合条件を否定するド・モルガンの法則と、その限界を扱った。数でない値に対しては、!(a < b) は a >= b と同値ではない。
代入・副作用・未定義動作
レッスン 代入・副作用・未定義動作 は、式の値とその作用を区別した。代入は代入された値をもち、変数を変える式であり、x++ はもとの値を、++x は新しい値をもつ。式の木はその枝を計算する順序を定めないので、同じ変数に対する二つの作用、あるいは作用と読み出しが、互いに順序なく起これば、その式は意味を失うことを示し、C++17 が何に順序を与え、何を未規定のまま残したかを明確にした。四つの段階(定義された動作、処理系定義の動作、未規定の動作、未定義の動作)の一覧をまとめ、コンパイラはプログラムに未定義動作がないと仮定して推論することを説明し、一覧のそれぞれの場合について、どの道具がそれを検出するかを述べた。
ビットと数学ライブラリ
レッスン ビットと数学ライブラリ は、整数がビットの並びでもあることを教えた。&、|、^ は各列に論理結合子を適用し、~ はすべてのビットを反転し、シフトは 2 のべきを掛けたり割ったりする。ただし、シフト量が負でなく、型の幅に達しないことが条件である。これらを使って、ビットを調べ、立て、下ろし、反転するマスクを組み立てた。これらの演算子は関係演算子より結びつきが弱いので、x & 1 == 0 は見かけどおりのことを問わないこと、そして ^ はべき乗ではないことに注意を促した。最後にライブラリを扱った。<cmath>、<numbers>、<numeric>、<bit> は正しく、確かめられた計算を提供し、それぞれに事前条件がある。たとえば絶対値の事前条件であり、最小の整数には絶対値が存在しない。
コンテンツを読み込んでいます…