『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, macOS Ventura 13.3.1, clang 14.0.3]
問1.6.1-6の解法は以下の通りです。
プログラミングの学習と言うよりも頭のトレーニング的な感じです。
真偽が確定していれば計算機は作業を止めますが、人間の作業や業務においては無駄な真偽評価をすることが多々あります。モチベーションが下がるだけですね。特に日本人はやりがち。
ようやく第1章が終わりました。次の章をどれにするかは興味本位で決めたいです。
#include <stdio.h>
#define PRINT3(x, y, z) printf("x = %d\ty = %d\tz = %d\n", x, y, z)
int main() {
int x , y, z;
// 問1.6.1
x = y = z = 1;
++x || ++y && ++z;
PRINT3(x, y, z);
// ++x || (++y && ++z)
// 計算機は左から評価を行う
// 計算1: ++xによりx = 2となりTRUE
// 計算2: ||を読込み、すでに左がTRUEなので計算終了
// よって、x = 2, y = 1, z = 1
// 問1.6.2
x = y = z = 1;
++x && ++y || ++z;
PRINT3(x, y, z);
// (++x && ++y) || ++z
// 計算1: ++xによりx = 2となりTRUE
// 計算2: &&を読込み、++yによりy = 2となりTRUE、左はTRUE
// 計算3: ||を読込み、すでに左がTRUEなので計算終了
// よって、x = 2, y = 2, z = 1
// 問1.6.3
x = y = z = 1;
++x && ++y && ++z;
PRINT3(x, y, z);
// (++x && ++y) && ++z
// 計算1: ++xによりx = 2となりTRUE
// 計算2: &&を読込み、++yによりy = 2となりTRUE、左はTRUE
// 計算3: &&を読込み、++zによりz = 2となりTRUE、TRUE && TRUE = TRUE
// よって、x = 2, y = 2, z = 2
// 問1.6.4
x = y = z = -1;
++x && ++y || ++z;
PRINT3(x, y, z);
// (++x && ++y) || ++z
// 計算1: ++xによりx = 0となりFALSE 左はFALSE確定のため++yは評価しない
// 計算2: ||を読込み、左がFALSEなので次に進む
// 計算3: ++zによりz = 0となりFALSE、FALSE || FALSE = FALSE
// よって、x = 0, y = -1, z = 0
// 問1.6.5
x = y = z = -1;
++x || ++y && ++z;
PRINT3(x, y, z);
// ++x || (++y && ++z)
// 計算1: ++xによりx = 0となりFALSE
// 計算2: ||を読込み、左がFALSEなので次に進む
// 計算3: ++yによりy = 0となりFALSE、&&を読込み右はFALSE確定のため++Zは評価しない
// 計算4: FALSE || FALSE = FALSE
// よって、x = 0, y = 0, z = -1
// 問1.6.6
x = y = z = -1;
++x && ++y && ++z;
PRINT3(x, y, z);
// (++x && ++y) && ++z
// 計算1: ++xによりx = 0となりFALSE
// 計算2: &&を読込み、左はFALSEのためFALSE確定。++yは評価しない
// 計算3: &&を読込み、左はFALSEのためFALSE確定。++zは評価しない
// 計算4: FALSE && FALSE = FALSE
// よって、x = 0, y = -1, z = -1
return 0;
}
x = 2 y = 1 z = 1
x = 2 y = 2 z = 1
x = 2 y = 2 z = 2
x = 0 y = -1 z = 0
x = 0 y = 0 z = -1
x = 0 y = -1 z = -1