プログラミング実習I 教科書の正誤表†
『C言語によるプログラミング 基礎編 第2版』の明らかな誤植だけでなく、初学者には混乱の元になる無駄な記述を以下に指摘します。
2019年以降に発行されたものでは、いくつか修正されています。
また、新しい教科書 を書いていますので、こちらも参照してください。
変数名や関数名の命名規則に、C言語では「すべて小文字、単語は_をはさんで連結する」というスネークケースが用いられることが多いですが、「単語の先頭を大文字にして隙間なくつなげる」というキャメルケースの用いられている部分がところどころに見られます。スネークケースで統一されるよう、変数名は以下のように読み替えるのがよいでしょう。
- p.71 リスト3.4
- 『Large』→『large』 4ヶ所
『Small』→『small』 3ヶ所
- p.257 リスト7.8
- 『Tokyo』→『tokyo』 2ヶ所(固有名詞の表記を優先して先頭大文字にするという考え方もある)
- p.332からp.333までとp.336
- 『FileName』→『filename』 多数
- p.64 表3.3
- long doubleの使用ビット数(最低保証)は、言語仕様上はないはずです。少なくとも80ではなく、VisualStudioのあるバージョンでは64です。
- p.65 図3.1の4行上
- 『(この表現方法はコンピュータによって異なります)』→『(この表現方法もコンピュータによって異なります)』あたかも整数型と浮動小数点で状況が異なるかのような言い回しですが、整数値のマイナス表現にもバリエーションがあります。(そのことには触れられてないようです。)
- p.65 図3.1
- 浮動小数点の内部表現には、「符号部」を含める必要がありますが、この図では抜けています。
- p.65 表3.5
- 値の範囲には「±1.7×10^(-308)〜±1.7×10^(308)」のように、複号が2回登場しますが、複号同順なのか任意なのか、どちらか読み取れませんし、どちらでも間違っています。まず、0は含める必要があります。次に、正の大きな値は1.7e+308で合っていますが、正の小さな値は、2.2e-308(正規化数)あるいは4.9e-324(非正規化数)のどちらかになるはずです。最後に、負の値は、正の値の符号違いです。
- p.65 下から1行目
- 『精度がよい』→『精度が同じかよい』
- p.66 coffee break 内3行目
- 『<limit.h>で定義』→『<limits.h>で定義』
- p.66 coffee break 内
- 「最小値」という単語が、文脈によって2通りの意味に用いられていることに注意。「doubleの最小値」には0より大きい正規化数という前提がついているのに対して、「intの最小値」にはその前提がありません。なお、前提なしの「doubleの最小値」は -DBL_MAX です。
- p.75 下から4行目
- 『全体で15桁、小数点以下3桁』→『全体で少なくとも15桁、小数点以下がちょうど3桁』
- p.102 13行目(箇条書きの次の行)
- 『手順1および4に』→『手順2および4に』
- p.145 <<プログラムの形式>> 4.7
- フローチャートの下から戻る矢印の先が、「初期化」のマスの上に入っていますが、上ではなく下に入るべき。
- p.169 リスト5.6の直前の段落からリスト5.7まで
- 『また、関数の定義では、その多くを省略することができます...』→関数の定義では、C言語の旧規格との互換性のために、省略できるキーワードがいくつかありましたが、省略するメリットはありませんのできちんと記述するようにしましょう。なお、C99 からは省略時の動作保証もなくなっています。
- p.169 脚注15
- 『引数を省略するとvoid型の引数となります。』→『引数を省略すると、引数の型チェックがされなくなり、どんな引数で呼び出してもエラーになりません。』
- p.207 下から2行目
- 『4つの変数』→『5つの変数』
- p.208 図6.5
- name配列の[8]の箱が余分。
- p.219 上から5行目の数式
- 分散の式が途中からおかしくなってます。最後の項はカッコの位置を次のようにします。(あるいは、カッコは不要です。)
- p.238 下から1行目
- 『int a[3][2] = {1,2,3,4,5,6}; と定義することもできます。』→『int a[3][2] = {1,2,3,4,5,6}; という記述はエラーにはなりませんが、「初期化子の周りに中括弧がありません」といった警告が出ることがあります。』
- p.251 リスト7.2 のタイトル
- 『配列を文字に格納する』→『配列 に 文字 を 格納する』
- p.251 リスト7.3 の直前の段落から p.252 リスト7.4まで
- 『ところで、リスト7.2には...少しトリッキーに感じられるかもしれませんが...』→削除(トリッキーですので、真似しないでください。)
- p.261 リスト7.11 上から9行目(下から7行目)
- 『gets(telegram); /* 電文の入力 */』→『fgets(telegram, sizeof telegram, stdin); if (telegram[strlen(telegram)-1] == '\n') { telegram[strlen(telegram)-1] = '\0'; } /* 電文の入力 */』
gets関数は新しい言語規格C11で廃止されましたので、コンパイラによっては使用できません。fgets関数が似た動作を行いますが、末尾の '\n' は '\0' に置き換わりません。
- p.262 落し穴 7.4 下から1行目
- 『getsを使いましょう。』→『fgetsを使いましょう、ただし末尾に改行が付きます。』
- p.277 5行目
- 『5.5.4項で学んだ通用範囲(通用範囲)』→『5.5項で学んだ通用範囲(スコープ)』
- p.297 最初の段落からの4つの段落
- 『次に構造体タグの省略について...警告を出すコンパイラも存在します。』→構造体タグを省略する手法は、その構造体を他の場面で利用できなくなるので、通常は用いられません。後述の9.5.1節(p.319)のように、typedef と組合せて型名を名付ける場合には、構造体タグを省略する手法がよく用いられます。
- p.300 リスト9.1
- 構造体がmain関数内で宣言されていますが(しかも変数定義を同時に行なっていますが)、こうするとこの構造体は通用範囲がmain関数に限定されてしまい、他の関数で用いることができませんので、このような使い方はしません。通常は複数の関数で扱えるように、構造体の宣言は関数の外側(特にプロトタイプ宣言の直前)に記述します。そして変数定義は分離することになります。
- p.312 リスト9.5の2行上
- プログラム(6.12)→プログラム(6.13)
- p.315 本文の下から9行目(print_address()関数内)
- printf(" zip:%l\n", addr.zip);→printf(" zip:%d\n", addr.zip);
10章†
- p.345 リスト10.7
- プログラムの中程で「if( (fp=fopen()) == NULL)」とNULLとの比較が記述してあるのに、もう少し下では「while(fgets(string, STRING_SIZE, FP))」とNULLとの比較が省略されていて、一貫性に欠けます。このページの2行目には「fgets関数はNULLを返します」との記述があるので、「while(fgets(string, STRING_SIZE, FP) != NULL)」と明示的に書くのがよいでしょう。