『C言語によるプログラミングの基礎』の疑問点†
授業の教科書『C言語によるプログラミングの基礎』(田中敏幸著、コロナ社)の非公式で勝手な正誤表です。第1版第2刷(2004年1月15日発行)の記述に基づいています。
このページの内容については、まったく保証しません。
2.3†
- p.11 「#include <stdio.h> これはプリプロセッサといいプログラムの中で使う関数を指定する部分である。 … プリプロセッサとしてどのようなものを用いるかは」
- プリプロセッサは前処理を行うソフトウェアのことなので、この部分は「#include <stdio.h> これはプリプロセッサ指令といい … ヘッダファイルとしてどのようなものを用いるかは」とするべきだろう。
- 同 「どのような場合でもstdio.hは必ず宣言しておかなければならない」
- 初心者向けの説明とは思うが、そのソースファイルでprintfなどの標準入出力関数を用いないときはstdio.hは不要である。
- p.12 「関数の最後には必ず戻り値を返す関数が必要となる。この戻り値を返す関数がreturnである」
2.4†
- p.16 「C++が開発されたときに、改行までを一つの単位としてコメント文にする方法も付け加えられた」
- 誤りとはいえないが、「//」型のコメントはC言語の先祖にあたるBCPLから復活したものである。
3.8†
4.2†
- p.42 「Visual C++ではプログラム中に実数値を書くとすべて倍精度とみなされる」
- Visual C++だけでなく、倍精度(double)になるのが標準規格である。
- p.44 「条件が満たされたとき(条件の値が1のとき)」
- 初心者向けの説明とは思うが、真と判定されるのは条件の値が0以外のときである。
4.3†
- p.56 「インクリメント演算子(++)とデクリメント演算子(--)は、浮動小数点(実数)の変数に対して用いることはできない」
4.4†
- p.68 「最近では、プログラミングの際に、特殊な場合を除いてgoto文は使わないというのが一般的になっている」
5.2†
- p.82 「これはPascalなどのプログラミング言語で用いられた書法だが、最近では、C言語でもこのようにmain関数を最後に置くプログラムがよく書かれるようになった」
- Pascalについては言語仕様で定められている。CについてはANSI Cの制定(1989年)以来、増えたのではないかと思われるが、これも「最近」や「よく」という表現がどの程度のことを言っているのだろうか…。
- p.86 「階乗など一部のアルゴリズムに使われているだけのようである」
- 一部かもしれないが、重要なアルゴリズムに再帰を使うものは少なくない。ほとんどループを使わず、代わりに再帰を使うプログラミング言語もある(すべてのループは再帰でも表現可能である)。
5.3†
- p.89 「5.3.2 外部変数(extern)」の説明
5.4†
- p.95 「stdio.hはプログラムの最初に必ずインクルードしなければならない」
- そのソースファイルのなかで、printfなどの標準入出力関数を用いないときはstdio.hは不要である。
- p.96 「#define PISQR PI*PI」
5.5†
- p.102 リスト5-16
- p.104 「理由についてははっきりしないが、2次元以上の配列で(1)の方法を用いると、プログラムが正常に実行されない場合がある」
- 本当だろうか? たとえば、Visual C++のどれかのバージョンでは、これが正常に実行されないのだろうか?
6.1†
- p.129 「読み込み更新"r+"は、まずファイルの読み込みを行って、その後で書き出しを行う」
- "r+"はファイルの内容を保持したまま、読み書き可能でオープンするものである。いったんオープンすれば、読み込みと書き出しの順番は自由なのではないだろうか?
- p.131 「オープンしたファイルの操作が終了したら、必ずクローズしなければならない」
- 心構えとしてはそうであるが、規格上、オープンされたファイルはプログラム終了時にすべて自動的にクローズされる。
- p.133 実行結果6-2
7.2†
- p.151 「コンピュータの処理能力が低く、… プログラムの高速化のために*(a+i)のようなポインタ演算が好まれていた。初期のCプログラミングの本では、できるだけポインタ表現を使うよう心がけていたものが多く見られる。現在では、配列a[i]という書式を用いても …」
- *(a+i)とa[i]についていえば、今のコンパイラでも昔のコンパイラでも翻訳結果に違いはないだろう(アドレスレジスタ+インデックスレジスタ)。*p++とa[i++]のことならばそういうこともあるかもしれないが、Cを使い慣れていれば特にポインタ表記のほうが分かりにくいということはないだろう。
- p.154 「sizeof()演算子」
- 「()」は演算子の一部ではないので、「sizeof演算子」でよい。
- p.165 リスト7-13
- 「#include <stdlib.h>」がない。
- 関数keisanで、スタック上のアドレス(自動変数bのアドレス)を呼び出し元の関数にreturnしている。keisanの中のbの宣言にstaticをつけるか、bはmallocによってヒープに確保しなければならない。
7.3†
- p.172 「この場合にはポインタと配列はまったく同じことを意味する」
- 配列名はその先頭要素へのポインタに適宜変換されるが、ポインタとまったく同じではない。具体的には、sizeof演算子での扱いが違う。sizeof(array)は配列全体のサイズであるが、sizeof(ptr)はポインタ変数1個のサイズになる。