著者:西尾 泰和[にしお・ひろかず](1981-) ソフトウェア・エンジニア。
シリーズ:WEB+DB PRESS plus
「コーディングを支える技術」著者公式ページ
コーディングを支える技術 著者公式ページ - 西尾泰和のScrapbox
コーディングを支える技術――成り立ちから学ぶプログラミング作法:書籍案内|技術評論社
【目次】
但し書き [ii]
はじめに [iii]
謝辞(2013年3月 西尾泰和) [iv]
本書の構成 [v]
サンプルコードのダウンロード [vi]
目次 [vii-xvi]
第1章:言語を深く効率的に学ぶには 001
1.1 比較から学ぶ 002
決め事は言語によって異なる
C言語とRubyにおける真偽値
Javaにおける真偽値
1.2 歴史から学ぶ 004
言語設計者の意図を理解する
どの言語を学ぶべきかは誰にもわからない
言語に依存しない普遍的な知識を学ぶ
1.3 まとめ 006
第2章:プログラミング言語を俯瞰する 007
2.1 プログラミング言語誕生の歴史 008
ケーブルをつなぐ
プログラム内蔵方式へ
FORTRANの登場
2.2 プログラミング言語の生まれた目的 011
無精――プログラマの三大美徳の一つ
言語により異なる「楽さ」の意味
何を楽にしたいのか
どんなプログラムを書くのを楽にしたいのか
2.3 まとめ 014
第3章:文法の誕生 015
3.1 文法って何だろう? 016
演算子の優先順位
文法は言語設計者が決めたルール
3.2 スタックマシンとFORTH 018
計算の流れ
計算順序をどう表現する?
現代にも生きるスタックマシン
3.3 構文木とLISP 021
計算の流れ
計算順序をどう表現する?
現代にも生きる構文木
3.4 中置記法 025
構文解析器
ルールの競合
3.5 まとめ 028
Column 理解を確認するためにはまずアウトプット 023
Column 何を学べがよいかがわからない理由 026
第4章:処理の流れのコントロール 029
4.1 構造化プログラミングの誕生 030
4.2 ifが生まれる前 031
ifはなぜあるのか
if……elseはなぜあるのか
アセンブリ言語での表現方法
C言語での表現方法
if……elseを使うメリット
4.3 while ――繰り返しのifを読みやすく表現 036
whileを使った表現方法
whileを使わない表現方法
4.4 for ――数値を増やしながらのwhileを読みやすく表現 037
forを使った表現方法
forを使わない表現方法
foreach ――処理の対象で繰り返しを制御
4.5 まとめ 040
第5章:関数 041
5.1 関数の役割 042
理解――組織のたとえ
再利用――部品のたとえ
プログラムにおける再利用の特徴
5.2 戻る命令 045
関数の誕生
戻る先を記録する専用のメモリ
スタック
5.3 再帰呼び出し 050
入れ子構造のデータを効率的に処理
入れ子構造を扱う方法
forでは表現できない
再帰呼び出しを使う
再帰呼び出しの実行の流れ
5.4 まとめ 056
Column 名前 047
第6章:エラー処理 057
6.1 プログラムも失敗をする 058
6.2 失敗をどうやって伝える? 059
返り値で失敗を伝える
失敗を見落とす
エラー処理のせいでコードが読みづらい
ジャンプでエラー処理をまとめる
失敗したらジャンプする
UNIVAC Iの場合
COBOLの場合
PL/Iの場合
6.3 失敗しそうなコードを囲む構文 066
John Goodenoughの主張
CLUへの導入
C++への導入
Windows NT 3.1への導入
6.4 出口を1つにしたい 069
なぜfinallyを導入したのか
対になる処理を確実に行いたい
finallyによる解決
finallyのないC++での解決
D言語のscope(exit)による解決
6.5 どういうときに例外を投げるか 073
関数呼び出し時に引数が不足している場合
配列の範囲外を取得しようとした場合
間違えたらすぐに例外を投げてほしい
6.6 例外の伝搬 077
例外が伝搬する問題点
Javaの検査例外
検査例外が普及しない理由
6.7 まとめ 081
Column 具体的な知識と抽象的な知識 079
Column 噛み砕く 080
Column 必要なところからかじる 082
第7章:名前とスコープ 083
7.1 名前はなぜ必要だったか 084
どうやって名前を付けるか
名前の衝突
衝突を回避するには
長い変数名を付ける
スコープを利用する
7.2 スコープの進化 088
動的スコープ
どのように動作するか
問題点
静的スコープ
動的スコープは対応表がコード全体から読める
静的スコープは関数ごとに対応表を分ける
7.3 静的スコープは完成形? 095
ネストした関数の問題
外のスコープへの再束縛の問題
Pythonでの解決方法
Rubyでの解決方法
7.4 まとめ 101
Column ほかの言語でのスコープは? 095
第8章:型 103
8.1 型とは何か 104
8.2 数値をオンとオフで表現する方法 105
位取りの発明
7セグメントディスプレイ
そろばん
8.3 1つの位に必要なランプはいくつか? 108
10進法から2進法ヘ
8進法と16進法
8進法
16進法
8.4 実数はどうやって表現しよう 113
固定小数点数――小数点がどこに付くか決める
浮動小数点数――どこからが小数部かの情報自体を値に含める
どのような考え方か
IEEE 754で定められた浮動小数点数のしくみ
問題点
8.5 型は何のため? 116
ないとどう困るのか
初期のFORTRANでの型
言語処理系に変数の種類を教える
暗黙の型昇格
整数同士,浮動小数点数同士の演算
片方が整数で片方が浮動小数点数の演算
問題点
書き方で区別する言語
8.6 型のいろいろな展開 122
ユーザ定義型とオブジェクト指向
仕様としての型
公開と非公開を分ける
インタフェースへの発展
型ですべての仕様を表現する世界が来るか
総称型,ジェネリクス,テンプレート
C++の場合
Javaの場合
Haskellの場合
動的型付け
どのように実現しているか
メリットとデメリット
型推論
Haskellと型推論のないC言語の比較
Haskellの型推論
Scalaの型推論
強い型でバグのないプログラムが作れるか
8.7 まとめ 133
Column おおまかにつかんで徐々に詳細化する 134
第9章:コンテナと文字列 135
9.1 いろいろな種類のコンテナがある 136
9.2 なぜいろいろな種類のコンテナがあるのか 137
配列と連結リスト
配列に値を挿入する場合
連結リストに値を挿入する場合
連結リストの模式図
連結リストの長所と短所
言語による違い
9.3 辞書,ハッシュ,連想配列 143
ハッシュテーブル
木
要素を取り出す時間
木の場合
ハッシュテーブルの場合
万能のコンテナはない
9.4 文字とは何か 150
文字集合と文字符号化方式
コンピュータ以前の符号化
モールス符号
ボーコード
EDSACの文字コード
ASCIIとEBCDICの時代
日本語エンコーディング
ISO-2022-JP
Shift_JIS
EUC-JP
Shift_JISがプログラムを壊す
マジックコメント
Unicodeによる統一
9.5 文字列とは何か 162
長さの情報を持つPascal文字列,持たないC文字列
NUL文字で文字列の終わりを表現する
NUL文字にまつわる不具合の例
1文字16bitのJava文字列
Python 3で行われた設計の変更
Ruby 1.9の挑戦
9.6 まとめ 168
Column O記法――計算時間とデータ量の関係を簡潔に表す 141
第10章:並行処理 169
10.1 並行処理とは何か 170
10.2 細かく区切って実行する 171
10.3 処理を切り替える2通りの方法 171
協調的マルチタスク――切りの良いところで交代する
プリエンプティブマルチタスク―― 一定時間で交代する
10.4 競合状態を防ぐには 173
競合状態の3条件
共有しない――プロセスとアクターモデル
プロセスではメモリを共有しない
共有しないアプローチは成功したか
アクターモデル
書き換えない―― const,val,Immutable
割り込まない
協調的なスレッドを使う――ファイバー,コルーチン,グリーンスレッド
割り込まれると困る処理中は印を付ける――ロック,ミューテックス,セマフォ
10.5 ロックの問題点と解決策 180
ロックの問題点
デッドロックが発生してしまう
合成できない
トランザクショナルメモリによる解決
トランザクショナルメモリの歴史
ハードウェアによる実装
ソフトウェアによる実装
トランザクショナルメモリは成功するか
10.6 まとめ 184
第11章:オブジェクトとクラス 185
11.1 オブジェクト指向とは何か 186
言語によって違う「オブジェクト指向」の意味
オブジェクトは現実世界の模型
クラスとは
11.2 変数と関数を束ねて模型を作る方法 190
11.3 方法1:モジュール,パッケージ 191
モジュール,パッケージとは何か
Perlのパッケージでオブジェクトを作る
モジュールだけでは足りない
データ置き場は個別に
引数に個別のハッシュを渡す
初期化の処理もパッケージに入れる
ハッシュとパッケージを結び付ける
11.4 方法2:関数もハッシュに入れる 198
ファーストクラス
関数をハッシュに入れる
複数のカウンタを作る
共有してよいモノをプロトタイプに移す
プロトタイプの動作
new演算子で効率的に記述する
これがオブジェクト指向?
11.5 方法3:クロージャ 206
クロージャとは
なぜクロージャと呼ぶ?
11.6 方法4:クラス 208
Hoareの考えたクラス
C++のクラス
仕様としての役割
クラスが持つ3つの役割
11.7 まとめ 210
第12章:継承によるコードの再利用 211
12.1 継承とは 212
継承に対するさまざまな考え方
一般化/特殊化
共通部分の抽出
差分実装
継承は諸刃の剣
リスコフの置換原則
12.2 多重継承 218
1つのモノを複数の分類に
実装の再利用に便利な多重継承
12.3 多重継承の問題点――またしても衝突! 220
解決策1:多重継承を禁止する
委譲
インタフェース
解決策2:メソッド解決順序を工夫する
深さ優先探索の問題点
C3線形化で順序を決める
解決策3:処理を混ぜ込む(Mix-in)
Pythonの場合
Rubyの場合
解決策4:トレイト
名前が衝突したときの振る舞い
提供するメソッドと要求するメソッド
ほかにもいろいろな機能が……
トレイトが広まりつつある
12.4 まとめ 234
Column 端から順番に写経する 235
あとがき [236-237]
索引 [238-246]
著者略歴 [247]