読者です 読者をやめる 読者になる 読者になる

if と else の思考術

Book

ifとelseの思考術 プログラマ脳育成講座

ifとelseの思考術 プログラマ脳育成講座

かなり遅くなったけど書評です。ただ、セオリーほどのぶっ飛び具合がないのが残念なところ。

全体

まず、この本全体にわたって、「アルゴリズム」という言葉は何回か出てくるんだけど、データ構造が一回もでてこない。
アルゴリズムとデータ構造のどちらが重要かって聞かれたら、迷わずデータ構造と答えるんだけど、どうもそういうのはプログラマ脳じゃないのかな。あー残念、プログラマ脳持ってないや。


それと、セオリーでは一行コメント使いまくりだったのに、この本では全然つかってない不思議。

コンピュータが好きになる必要はあるのか

コンピュータが好きでプログラミングが楽しくなければ、プログラマ (自分の思いどおりにプログラムを作れる人) にはなれません。

if と else の思考術 (P.2)

とあるけど、そんなことはないと思う。
実際、周りにはコンピュータは別に好きじゃないけど、すさまじいプログラマもいたし、プログラミングを楽しいと思っていなくて、完全な手段としてしか捕らえていない人ですばらしいプログラマに会ったこともある。
さらに、

ハードのことがわかりませんと言うプログラマに仕事を頼む気になれないはずです。

if と else の思考術 (P.22)

ともあるけど、分野によっては別にハードのことがわからなくても問題はないと思うし、実はそれなりにハードのことがわかっている人が謙虚さからわからないと言っている可能性もある。
ハードのことを知っていたほうがいいのには同意するけど、ちょっと極端すぎるというかなんというか。


あと、五大装置は今になっては必要ない知識だと思うんだよね。
それを知っていたところでいったいなんの役に立つのか全くわからない。
そんなことより、PC を構成するパーツの役割を理解するほうがよほど役に立つと思うんだけど。

CPU は「演算装置」と「制御装置」を兼務しています。

if と else の思考術 (P.30)

と言うけれど、実際にはいまどきの CPU にはキャッシュメモリが結構な量搭載されてることを考えると、「記憶装置」も兼務してると言えるだろうけど・・・やっぱりこんな分類に意味があるとは思えないんだよな。
なんだろう、出力は出力装置に出力するだけじゃなくて、実際にはファイル出力とかもあるわけで、その場合出力先は記憶装置になってしまうわけで*1・・・

情報が古い

多くの Windows パソコンでは、インテル社の Pentium または AMD 社の Athlon などという製品名の CPU が使われています。

if と else の思考術 (P.30)

多くのパソコンは、32 ビット CPU を搭載しています。

if と else の思考術 (P.43)

コンピュータは一度に 1 つの処理しかできないので、配列の要素を 1 個ずつ繰り返し処理することになるのです。

if と else の思考術 (P.157-158)

コード

基本メニュー コード トッピング コード
醤油ラーメン 10 チャーシュー 1
味噌ラーメン 20 モヤシ 2
塩ラーメン 30 コーン 3

慎重にコードを取り決めないと、おかしな結果になってしまいます。
実は、このラーメン屋さんのコードには問題があります。醤油ラーメン (10) に、チャーシュー (1) とモヤシ (2) をトッピングしたとしましょう。「10 + 1 + 2 = 13」という計算結果になります。「13」という値は、醤油ラーメン (10) にコーン (3) をトッピングした計算結果 (10 + 3 = 13) と同じです。したがって

if と else の思考術 (P.36)

足すなw
DB に格納することを考えるなら、トッピングはレシピとして表せばいいだろうし、プログラム中ならそれぞれ別の変数を割り当てるとかすればいい。
何でもかんでもビットで考えればいいってわけじゃない。

2 進法

10 進数が書き終わったら、その横に 8 ビット (8 桁) の 2 進数で同じ数を書いてください。

if と else の思考術 (P.44)

なんで 8 ビット?負数を扱うわけでもないんだから、何ビットかなんて気にしなくていいと思うんだけど。

10 進数の足し算では 10 で桁上がりしますが、2 進数では 2 で桁上がりします。
・・・
10 進数の引き算では上位桁から借りてくるのは 10 ですが、2 進数では 2 を借りてきます。

if と else の思考術 (P.45)

2 で桁上がり、2 を借りるって・・・10(2) で桁上がり、10(2)を借りる、の方がいちいち変換するよりいいと思うんだけど。

フローチャート

新人研修の講師をしていると「どうにかプログラムは作れますが、フローチャートを描くことが苦手です」と言う新人さんをよく見かけます。このような新人さんは、考えがまとまらないうちにプログラムを打ち込み始め、その実行結果 (正しくない実行結果) を見てからプログラムを修正するという作り方をしています。趣味でプログラミングするなら、このスタイルでもかまいませんが、プロを目指すならいけません。フローチャートを描いて考えをきちんと整理しないと、品質の高いプログラムを作れないからです。

if と else の思考術 (P.52)

コードを打ち始める前に考えをまとめる、ってのは大事だけど、フローチャートでやることじゃない。
それに、フローチャートを描いたからと言って品質の高いプログラムになる保証はないし。
フローチャートを描くのが苦手?それでいいじゃん。プログラマの仕事は図を描くことじゃなくて、プログラムを書くことなんだからさ。

プログラミング教材の選び方

プログラミング教材には、以下に示したような種類があります。書店に並んだ本がどれに該当するのかは、書名と表紙のデザインから判断してください。もちろん、手にとって内容も確認してください。

  1. プログラミングを楽しむ入門書
  2. 言語構文の概要を網羅した入門書
  3. 言語構文を詳細に網羅した解説書
  4. アルゴリズムのサンプル集
  5. プログラミングの Tips 集
  6. データベースプログラミングの解説書
  7. インターネットプログラミングの解説書
  8. その他
if と else の思考術 (P.63-64)

なにこの分類w
例えばオブジェクト指向関連の本は・・・その他だな。
コンパイラ関連の本は・・・その他だな。
ライブラリ関連の本は・・・その他だな。
バージョン管理やら開発手法やらの本は・・・その他だな。


それにしても、教材の選択方法適当だなぁ。表紙のデザインからいったい何を読み取れと?

Java と C

Java は、同じプログラムを異なるハードウェアで動作させることを目的に開発された言語です。したがって、Java のプログラムを通してコンピュータの仕組み (ハードウェア) をイメージすることはできません。それに対して、C 言語は、コンピュータの仕組みをイメージしやすい言語です。

if と else の思考術 (P.68-69)

Java より C の方がコンピュータの仕組みをイメージしやすいというのはまぁ、そのとおりだとは思うんだけど、果たしてそれが必要かどうかというのはちょっと疑問だな。
そもそも C の方がコンピュータの仕組みをイメージしやすいと言っても、 最近の CPU はアセンブリの命令とすら一対一にマッピングされた動作をしてないんだから、間違った「コンピュータの仕組み」をイメージしてしまう恐れもあるわけで・・・
それに、Java だって JVM という仮想のコンピュータ上で動いてることも考えると、別にそこが決め手になるようなものじゃないと思う。

ある IT 関連の雑誌で読者アンケートを取ったところ、「あなたが使える言語は何ですか」という質問に対して、圧倒的に答えが多かったのが C 言語です。

if と else の思考術 (P.69)

その雑誌、C を中心的に扱ってたりしてw
と、冗談は置いといたとしても、「C 言語できます!」な人に散々苦労させられた経験があるから、そんなアンケートに果たしてどれほどの意味があるのかが疑問だな。

C 言語をしっかりマスターすれば、Java の学習はゼロからにはなりません。C 言語と Java の言語構文には、共通する部分が多くあるからです。

if と else の思考術 (P.69)

えと、それ逆も言えますよね。

プログラミング言語の違いは、方言の違い程度のものです。

if と else の思考術 (P.70)

すげぇ、言い切った。正直、HaskellJava を方言程度の違いしかないと言えるようになれる気がしません。

複数のプログラミング言語を習得しているプロには、自分の「第一プログラミング言語」と呼べるものがあります。これは「プログラムを考えるときの基礎となる言語」もしくは「最も好きな言語」です。

if と else の思考術 (P.70)

もしくはって何だw
このノリ、あれですよね、ひとつの言語が使えるなら、他の言語は勉強しなくていい
自分の第一プログラミング言語 (最も好きな言語という意味で) は、JavaSQL ということになるだろうけど、他の言語を使っているときにこれらの言語で考えたりはしていない*2。言語が使えるようになるってのは、その言語で考えることができるようになることじゃないの?*3

ソースコードの読み方

#include <stdio.h>
しゃーぷ・いんくるーど・すたんだーどあいおー・てん・えいち

int main(int argc, char* argv[])
{
いんと・めいん・いんと・あるぐしー・ちゃー・こめ・あるぐぶい

・・・
しゃーぷ・いんくるーど・しょうなり・すたでぃお・てん・えいち・だいなり


と読んでいました。プログラミングの学習が進み、stdio が standard I/O を意味していることを知ってから、


すたんだーど・あいおー


と読むように変わりました。

if と else の思考術 (P.84-85)

arg は argument を意味してるんだから、「あるぐ」より「あーぐ」もしくは「あーぎゅ」と、char は character を意味してるんだから、「ちゃー」より「きゃら」と、* はポインタを表してるんだから、「ちゃー・こめ」より「きゃら・ぽいんた」と、[] は配列を表しているんだから、無視せずに「あーぐぶいのはいれつ」と読んだほうがいいんじゃなかろうか。
もっと言うと、argc は argument count から、argv は「argument vector もしくは argument value」 からきてるんだから・・・って、ここまでする必要はないか。

C 言語の構文のノリ

  1. データを変数で表し、処理を関数で表す
  2. 命令の末尾にセミコロンを置く
  3. { } で囲んでブロックを表す
  4. 関数のブロックの中では、はじめにまとめて変数を宣言する
  5. main 関数からスタートし、他の関数が芋づる式に呼び出される
if と else の思考術 (P.90-91)

C 言語では、処理で使われる変数を最初にまとめて宣言する (データ型と変数名を提示する) 約束になっている

if と else の思考術 (P.138)

C99 を持ち出すまでもなく、ブロックの先頭なら変数は宣言できるはずですが・・・?

4章の意義

4 章は、なんで存在するのかが全くわからない。その名も、「プログラミング入門講座で指導する方法」
・・・ちょっと待て、この本、「はじめに」で、

本書を手に取った皆さんは、プログラミングに興味がある人、もしくは将来の仕事としてプログラマを目指している人でしょう。

if と else の思考術

ってあるんですけど?
この章の存在意義っていったい・・・

バグではなく仕様です

たとえば「あいこで終わるのはおかしい」というバグをあげてくれた人に、「よく気がつきましたね。確かにそのとおりです!」と言ってあげましょう。「ただし、これはバグではなく仕様であるとも考えられます。バグを仕様だと言って逃げるのは、プロのプログラマでもまれにあることですが、皆さんは決して真似をしないように」と教えてあげましょう。プロの世界の話をすると、新人さんは大いに興味を持ってくれます。

if と else の思考術 (P.113)

えーと、バグではなく仕様です・・・?そういうのは仕様を決めてから言ってくださいよ。
つか、ほめたところで止めとけよ。その先はなんか、「自分が勝って終わらないと気がすまない」みたいな印象を受けるんだけど。

while 文

このバグの修正は、新たに while 文による繰り返し構文と、strcmp 関数が必要になります。それらの使い方を教えれば、この修正案を実現できます。main 関数の中にある処理の流れ全体を「do 〜 while」で囲むのです (リスト 4-8 のアミカケした部分)。

if と else の思考術 (P.116)

while 文には、

while (継続条件) { ・・・ }

do { ・・・ } while (継続条件);

という 2 種類の構文があります。

if と else の思考術 (P.273)

do-while 文は while 文じゃねー。
あと、上であげた部分の例に出されてるプログラム、strcmp 全然必要じゃないんだけど・・・

数学は数値を取り扱うものなのか

プログラミング言語の構文で数学のような表現 (変数、関数、数式) が使われるのはなぜか?という質問です。
このような質問をする新人さんの気持ちは、よくわかります。数学のような表現が使われる理由を知りたいのではありません。「私は数学が苦手なので、この先もっと難しい数学の表現が登場するのではないかと不安です」と言っているのです。筆者は「コンピュータと数学には、数値を取り扱うと言う共通点があるからです (表向きの答え)。中学 3 年か高校 1 年ぐらいまでの数学の知識があれば大丈夫ですから心配しないでください (質問者が求めている答え)」と回答しています。

if と else の思考術 (P.122)

なんというエスパー。
じゃなくて、コンピュータが数値を取り扱うもの、ってのは百歩譲るとして、数学が数値を取り扱うってのはどうなんだろ。なんかそれ数学のごく一部じゃ?とか思うんだけどな。

10 回ループ

とした方がよい (i < 10 ではなく、i <= 9 とした方がよい) のではないか、という疑問を持つ人がいます。
筆者の回答は「どうぞ自分の頭の中にある考えを素直にプログラムに表してください」です。ただし「ベテランプログラマは、"for (i = 0; i < 10; i++)" と書くのを好みます」と補足します。

if と else の思考術 (P.129)

なんでこう回りくどいのかね。素直に、「それが慣例となっていて、そうする方が誰もに読みやすくなるからです」でいいじゃん。なんかいちいち嫌味ったらしいんだよな、この人。

名前のつけ方

変数名は、データの意味を表す複数文字の名前にするべきですが、キーボードから入力された数値を格納する変数は特に意味のあるデータではないので、単に「a」という名前にします。a とした理由は、アルファベットの先頭の文字だからです。

if と else の思考術 (P.139)

理由になってねー!
単純に、input でいいじゃん。
この本ではしきりに、「サンプルを真似るのが大切」みたいなことを言ってるけど、これってサンプルを真似ることによる弊害だよな。

(1) プレイヤーが手を選択する関数
【関数名】
int getPlayerHand()
・・・
(2) コンピュータが手を選択する関数
【関数名】
int getComputerHand()
・・・
(3) 勝敗を判定する関数
【関数名】
int getWinner(int player, int computer)

if と else の思考術 (P.264)

get 好きだなおい。これらの関数の中に printf とか scanf とか使われてるのも素敵w
もしこれらに名前を付けるとしたら、上から

  • choosePlayerHand
  • decideComputerHand
  • judge

それと、関数名に英単語を使っておきながら、

ここでは、グー、チョキ、パーを表す「GU」「CHOKI」「PA」という定数だけでなく、

if と else の思考術 (P.265)

ってのが気に入らない。もしローマ字が使いたかったら、

  • JP_GU JA_GU
  • JP_CHOKI JA_CHOKI
  • JP_PA JA_PA

のようにわかりやすくしてほしい。


追記:
きむら(K) さんからコメントで指摘があったように、JP は日本を表すコードなので、日本語を表す JA に変更。

複雑なプログラム

複雑なプログラムは、「変数が多く」「入力が多く」「演算が多く」「表示する項目が多い」だけです。単純なサンプルの構造を覚えれば、複雑なプログラムも作れます。

if と else の思考術 (P.142)

・・・複雑なプログラムの定義は難しいけど、これ、「単純なサンプルの構造」と言ってることから、一関数内の話をしてるって時点でこの定義ではないことは確か。
サンプルの構造を真似てしまったがためにろくな設計もせず main に全部突っ込んでしまったという意味では複雑なプログラムだろうけど、それはなるべくしてなったというか・・・

美しいコード

ベテランエンジニアが書くソースコードは美しいものです。では、美しいとは何でしょう。それは、ソースコードの書式に統一性があることです。

if と else の思考術 (P.164)

ソースコードの書式に統一性があるだけで美しいと感じるとは・・・

スタイル

もしもスタイルを混在させるなら、関数のブロックは図 5-9 の (1) のスタイル、その他は図 5-9 の (2) のスタイルのように、使い分けを統一しましょう。

(1) ブロックの開始行の末尾に { を置くスタイル
for (i = 1; i < 10; i++) {
    ・・・
}

(2) ブロックの開始行の次の行の先頭に { を置くスタイル
for (i = 1; i < 10; i++)
{
    ・・・
}
if と else の思考術 (P.167)

逆じゃないの?
というかですね、書式の整形なんて IDE にやらせろよと本気で思ってるんですけど・・・
そんなこと人間のやることじゃないって。つか、そんなことに時間かけんなよマジで。仕事しろ仕事。

空行のタイミング

空行を入れるタイミングは、どこでソースコードを区切って読むかです。

if と else の思考術 (P.171)

空行のタイミングはむずかしいよね。なんか、空行で区切るくらいなら関数化してしまうというか・・・
そうなると空行入れるのもなんだかなー、ってなっちゃう。
で、その疑問に答えてくれるかなー、なんて期待したけど、関数化しろよというサンプルばっか。

アルゴリズム

アルゴリズムを数多く知ると、自分で考える習慣をなくしてしまう恐れがあるので注意してください。たとえば「2 つの整数の最小公倍数を求める」アルゴリズムは、どのようになると思いますか?
「どうせ、○○の△△法のような既存のアルゴリズムがあるのだろう」と思って自分で考えることをやめてしまったら、プログラマとしてよろしくないことです。アルゴリズムは常に自分で考えるものだからです。

if と else の思考術 (P.189)

うーん、これについては賛否両論になるかもしれないんだけど、アルゴリズムを常に自分で考えるのは非効率だし、品質を考えてもあまりよろしいことだとは思えない。
アルゴリズムを勉強する、という部分では自分で考えるべき、というか、自分で考えなかったら勉強にならない。でも、いざ仕事で使うとなると、標準ライブラリが用意してるならそれを使うべきだし、自作するべきではない。

アルゴリズムを手作業で覚えさせる危険性

今度は、手作業でアルゴリズムを体得する方法を紹介します。これは、筆者が IT 企業の新人研修で、実際に行っている方法です。

if と else の思考術 (P.207)

で、バブルソート、選択ソート、挿入ソートを手作業でやらせてるわけですけど・・・
この 3 つの中じゃ、挿入ソートは人間がやることによって O(n) 程度になってしまうと思うんだけど、そこらへんをどうフォローするのかが載ってない。


線形探索と番兵を使った線形探索も、差を感じられないと思う。本では、

このとき、配列の末尾を突き抜けることを心配しないで「○○か」「○○か」「○○か」・・・と言いながら、猛スピードでカードをめくってください。

if と else の思考術 (P.209)

とあるけど、人間は常に並べたカードの端を (短時間で) 意識することができるから、これもどうだろう。つか、正直間抜けだよね。

0の階乗に対応するのはそんなに面倒か?

数学では 0 の階乗を 1 とする約束になっていますが、ここでは対応しないことにします。

if と else の思考術 (P.230)

なぜだ

/* ループ版 */
int factorial_1(int n)
{
    int result, i;
    
    result = 1;
    for (i = 0; i < n; i++)
        result *= i + 1;
    return result;
}

/* 再帰版 */
int factorial_2(int n)
{
    return (n == 0) ? 1
                    : n * factorial_2(n - 1);
}

/* 末尾再帰版 */
int fact(int result, int count)
{
    return (count == 0) ? result
                        : fact(result * count, count - 1);
}

int factorial_3(int n)
{
    return fact(1, n);
}

うーん、どれも全然面倒じゃないんだけど・・・

恐怖の 1 本ソース

大きなプログラムを大きなまま一気に作ることはできません。もしもそれを行おうとしたら、俗に言う「恐怖の 1 本ソース」になってしまいます。恐怖の 1 本ソースとは、1 つのソースファイルの中に関数が 1 つだけ記述されていて、その処理内容が数百行〜数千行にもなっているものです。

if と else の思考術 (P.258)

だから、俗に言われてないから
セオリーでは漢字だったのに数字になってるってことは、矢沢さんの中でもあやふやなんでしょうね。
つか、数百行〜数千行だったらまだかわいいほうじゃないですか。

PC の分解は、組み立てよりも難しい

さらに興味が増したら、パソコンをバラバラに分解してから、組み立て直してください。その際の教材となるのが「パソコン自作マニュアル」のようなタイトルの書籍です。

if と else の思考術 (P.284)

PC の分解は難しいし、下手すると壊しかねないからやめたほうがいいんだけどな*4
それに、メーカー製だと保証がきかなくなるだとかあるし、スリム型だとかなり中身が詰まっててすごいし。
CPU が Athlon XP とかだと、CPU が逝きかねない*5


気になったところはもっとあったけど、いちいち突っ込んでると切りがないのでこの辺で。

*1:入力についてもそれが言える

*2:SQL を基礎にしてプログラムを考える?冗談はよしてくれ

*3:まぁただ、少なからず影響を受けることはあるけどね

*4:ピンを折ったり、コネクタ破壊したりってのはよくある話

*5:コア欠けというやつ。CPU クーラーをつけるときより、はずすときの方が危ない