私は現在「Accelerated C++」に取り組んでおり、第3章でこれに出くわしました:
// invariant:
// we have read count grades so far, and
// sum is the sum of the first count grades
while (cin >> x) {
++count;
sum += x;
}
著者はこれに続いて、不変式には特別な注意を払う必要があると説明しています。これは、入力が に読み込まれると成績x
が読み取られ、count + 1
不変式が真でなくなるためです。同様に、カウンターをインクリメントするsum
と、最後のカウント成績の合計ではなくなります (ご想像のとおり、これは学生の成績を計算するための従来のプログラムです)。
私が理解していないのは、なぜこれが重要なのかです。確かに、他のほぼすべてのループについて、同様のステートメントが当てはまりますか? たとえば、これは本の最初のwhile
ループです (出力は後で入力されます)。
// invariant: we have written r rows so far
while (r != rows) {
// write a row of output
std::cout << std::endl;
++r;
}
r
出力の適切な行を書き込んだら、他の例と同様に、をインクリメントするまで、不変条件は確実に false になりますか?
この 2 つの条件の違いは何ですか?
編集:すべての返信に感謝します。わかったと思いますが、念のために「承認された回答」を選択する前に、もう少しそのままにしておきます。これまでのところ、すべての回答は基本的に同意しているため、公正とは思えませんが、やる価値はあると思います。
以下に要求された元の段落:
「このループの不変条件を理解するには、特別な注意が必要です。なぜなら、while の条件には副作用があるからです。これらの副作用は、不変条件の真実に影響を与えます: cin >> x を正常に実行すると、不変条件の最初の部分、つまり、 count grades-false を読みました. したがって、条件自体が不変式に与える影響を説明するために、分析を変更する必要があります。
条件を評価する前に不変式が真であったことがわかっているので、すでにカウント グレードを読み取っていることがわかります。cin >> x が成功した場合、count + 1 の成績を読み取ったことになります。カウントをインクリメントすることで、不変式のこの部分を再び真にすることができます。ただし、これを行うと、不変式の 2 番目の部分 (合計は最初のカウントの成績の合計であるという部分) が改ざんされます。成績を数えます。幸いなことに、sum += x; を実行することで、不変式の 2 番目の部分を真にすることができます。そのため、その間の後続の旅行では不変式全体が真になります。
条件が false の場合、入力の試行が失敗したため、それ以上データを取得できなかったため、不変条件は依然として true であることを意味します。その結果、while が終了した後の状態の副作用を考慮する必要はありません。」