わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

p=p-1ではなくp=1-p

 いきなりですが問題です.Cで書かれた,次のコード断片をご覧ください.

    while (n > 0) {
        /* nの値を出力 */
        m = marble(n);
        /* pが0なら「Alice」,1なら「Bob」を出力 */
        /* 何個取ったかを出力 */
        n = n - m;
        p = 1 - p;
    }

 marbleは,おはじきのことです(おはじき取りのゲームのルール,ナレーションやり直しにルールを書いています).「m = marble(n);」は,おはじきの残りの数nに対して何個取るかを(関数marbleで計算して,その結果を)mに代入し,「n = n - m;」により,おはじきの残りの数を減らします.
 では「p = 1 - p;」は何を行うのでしょうか.


 さっそくですが解答です.3行前に「pが0なら「Alice」,1なら「Bob」を出力」と書かれています.そこでpのとり得る値は,0と1のいずれかとみなします.そうすると,「p = 1 - p;」により,pの値は,0なら1に,1なら0になります.より具体的にはこうです.

  • この式を評価する前の,pの値が0なら,p = 1 - 0で,1がpに代入されます.
  • この式を評価する前の,pの値が1なら,p = 1 - 1で,0がpに代入されます.

 先週の授業で解説を行いました.また上記のコード(コメントはprintfなどにして)は,昨年度と今年度の第2クォーター科目の最終回に公開した,プログラミング科目の「Cコース」向け説明資料に,第3クォーターの科目ではこういうコードを含むプログラムを作成・実行しますと,解説していたのでした.
 「p = 1 - p;」であり,「p = p - 1;」ではありません---これだと,whileループの繰り返しの回数だけ,pを1ずつ減らしていくことになります.
 授業から離れ,ただしint型の変数pが0と1のいずれかしかとらないと仮定して,反転させるコードは,他にいくつか考えられます.最も字数が短い*1のは「p = !p;」です.1増やして,2になったら0にするという方針で,式を書くなら,「p = (p + 1) % 2;」で,これは少しアレンジして他の課題に取り入れました.排他的論理和演算子を使用して「p = p ^ 1;」と書くこともできます.1つの式にとらわれなければ,「if (p == 0) { p = 1; } else { p = 0; }」や「if (p) p = 0; else p = 1;」というのも認められます.後者のif文をもとに三項演算子で書き換えると,「p = p ? 0 : 1;」となります.
 しかしながら,「おはじき取りのゲームのプログラム」を学習してもらうにあたり,「p = 1 - p;」を他のコードに置き換えよという課題は,良いものとは言えません.むしろ,「手番の交代(AliceからBobに,BobからAliceに)」を,変数を使ってどのように表現すればよいかを学ぶことが,最も大事です.
 直接的にはif~elseですが,中括弧も含めると5行のコードを,1行に減らせるというのが,「p = 1 - p;」の面白いところと,思っています.「p = p - 1;」との違いは,(面白さの)2番目の要素です.


 昨年度の105分×7回の授業の資料の説明内容は,先週のうちに終わってしまいまして,今週木曜,第8回の授業資料を新たに作成中です.課題も新作となります.まずはサポート教員とTAに見てもらい,最終調整と,水曜にナレーションを行い,授業日に視聴やダウンロードなどをしてもらいます.
 クォーター科目・セメスター科目のいずれも,来週木曜は予備日となっています.1年生は引き続き履修する,第4クォーターのプログラミング科目は再来週からです.

*1:空白文字は字数に入れないものとします.