Accelerated C++ 第2章
このあたりはざっと流して行きたいけど、課題を丁寧にやってると結構時間がかかるな。
ループの不変量(Loop Invariant)、不変な表明
「不変な表明」は、契約による設計への「不変条件」の意味か。
invariantそのものには不変量、不変式の意味があり、おぼろげな記憶では、「loop invariant」=「ループで値が代わらない式」で最適化の話に出てくる(気がする)。
for (init-statement condition; expression) statement
ini-statementがあれっと思ったけど、C++だと初期化ができるのでこちらになり、Cと違う点。
C言語でもそうだが、式(expression)と式に ; をつけた式文との区別が曖昧な記述が多いね。
プログラムの完成
1文字ずつ出力するなら cout << '*' とするほうが素直じゃないかなと思うし、"*"とする文字列リテラルの領域を確保して・・などと貧乏くさい考えが浮かんでくる。
一方 ++c を1つにするため(だけ?)に else の中に if を入れ子にして { } も省略としているが、ここはやはり
- if のネストは避ける(多方向分岐はそのまま素直に書き下す)
- if/else の本体が1行しかなくてもブロックにする({ }で囲む)
としたい。
カウント:ものを数えるときに1からではなく、0からである理由
不変な表明で上手く説明されているように思う。
ただforの条件式は < を使う方になじみがあるなぁ。コンテナクラスのイテレータへのつなぎを意図しているのだろうけど。
課題
2-0,2-1
やってみた。
2-2
pad を vpad(垂直、上下) と hpad(水平、左右)に分ける。
const int hpad = 4; const int vpad = 2; const int rows = vpad * 2 + 3; const string::size_type cols = greeting.size() + hpad * 2 + 2; cout << endl; for (int r = 0; r != rows; ++r) { string::size_type c = 0; while (c != cols) { if (r == vpad + 1 && c == hpad + 1) {
2-3
pad を const でなくして、入力させるだけ。エラーチェックを考慮すると面倒。
2-4
greetingの前後の空白とかを考慮すると、空白だけ一気にというのは意外と面倒。*も含めて行単位で処理する方が判りやすい。
課題2-5へのつなぎ問題?
const string spaces(greeting.size(), ' '); cout << endl; for (int r = 0; r != rows; ++r) { string::size_type c = 0; while (c < cols) { if (r == pad + 1 && c == pad + 1) { cout << greeting; c += greeting.size(); } else if (r == 0 || r == rows - 1 || c == 0 || c == cols - 1) { cout << '*'; ++c; } else if (c == pad + 1) { cout << spaces; c += spaces.size(); } else { cout << ' '; ++c; } }
2-5
stringオブジェクトの生成と出力を一気にやるのが意図か。
高さを指定して二等辺三角形を表示する。
void tri(const int h) { for (int i = 0; i < h; i++) { cout << string(h - i - 1, ' ') << string(i * 2 + 1, '*') << endl; } }
2-6
1から10まで表示。
2-7, 2-8, 2-9
つまらない例だけど、一応やってみた。