プログラミング実習II情報 教科書の正誤表

『C言語によるプログラミング 基礎編 第3版』(1刷)の明らかな誤植だけでなく、初学者には混乱の元になる無駄な記述を以下に指摘します。

3章

p.61 上から2行目
『最初の31文字までが有効』→『少なくとも最初の31文字までが有効』
環境依存で、もっと長い変数名を区別することもあります。
p.61 上から8--9行目
『同じ変数として扱われる』→『同じ変数として扱われる可能性のある
環境によっては区別されます。
p.64 表3.3
「使用ビット数(最低保証)」について。浮動小数点数の使用ビットの規定は、言語仕様にはないはずです。(10進数での有効精度の桁数 ???_DIG の規定はあります。)特に long double は、精度が double 以上であることは保証されていますが、少なくとも使用ビット数の保証値は『80』ではなく、VisualStudioのあるバージョンのように『64』(つまりdoubleと同一)である環境も見受けられます。
p.64 表3.4
signedで表せる値の最小値が、-32768のように -2^n になるのは、マイナスを「2の補数」で実現した場合に限ります。C99では他に「1の補数」と「符号と絶対値」の2通りの実現方法が想定されており、この場合は最小値が -(2^n-1)(つまり最大値の符号違い)になります。
p.65 図3.3の4行上
『(この表現方法はコンピュータによって異なります)』→『(この表現方法コンピュータによって異なります)』
あたかも整数型と浮動小数点で状況が異なるかのような言い回しですが、整数値のマイナス表現にも3通りのバリエーションがあります。(p.68 の Coffe Break 3.4 で、「2の補数」であることが決まっているかのような説明も間違いです。)
p.65 図3.3
浮動小数点の内部表現には、「符号部」を含める必要がありますが、この図では抜けています。
p.65 表3.5
double の正の小さな値の 2.2251e-308 は正規化数に限った場合で、精度が落ちてよければ4.9e-324まで表せます。負の値や、float, long double でも同様に、より0に近い値まで表せます。
p.66 3行目
『精度がよい』→『精度が同じかよい』
p.66--67 coffee break 3.2 内
「最小値」という単語が、文脈によって2通りの意味で用いられています。「doubleの最小値」には0より大きい正規化数という前提がついているのに対して、「intの最小値」にはその前提がありません。なお、前提なしの「doubleの最小値」は -DBL_MAX です。
P.67 coffee break 3.3
intのビット数は、「アーキテクチャで提供される自然の大きさ」(K&R第2版日本語版)として選ばれます。演算が高速であることは、(考慮すべきですが)絶対的な条件ではありません。
p.78 上から4行目
『%lf』→『%Lf』printf() の %f と %lf の動作は同じです。long double には %Lf を使います。
p.78 下から1行目
『全体で15、小数点以下3桁』→『全体で少なくとも15文字、小数点以下がちょうど3桁』15文字で足りない場合は、必要な文字数まで自動的に増やして表示します。また、全体の文字数には、空白やピリオドも含めるので、数値の「桁」数とは違います。
p.79 上から2行目
『全体で15』→『全体で少なくとも15文字

4章

p.150 リスト4.11
7行目の変数定義は不要です。13行目と14行目の変数定義だけで十分です。

5章

p.184 リスト5.6の直前の段落からリスト5.7まで
『また、関数の定義では、その多くを省略することができます...』→関数の定義では、C言語の旧規格との互換性のために、省略できるキーワードがいくつかありましたが、省略するメリットはありませんのできちんと記述するようにしましょう。
p.184 脚注13
『引数を省略すると、void型の引数となります。』→『引数を省略すると、引数の型チェックがされなくなり、どんな引数で呼び出してもエラーになりません。』
voidの省略が「引数なし」の意味になるのは、C++やJavaなど、他の言語の場合です。
p.195 リスト5.12
5行目で定義された変数a,b,cが、初期化されないまま9行目で使用されています。『int a=1, b=2, c=3;』のように初期化しておきましょう。
p.195 リスト5.12 と p.196 2段落目
プロトタイプ宣言は、関数の一覧の役目もあるので、7行目のようにローカル変数と一緒に宣言して埋もれさせるようなことはせず、#include の直後の行(例えば2行目)に書き並べるのが標準手法です。
p.196 5.2.3節 1行目
『maz(24,12)』→『max(24,12)』
p.199 下から3行目
『総選択』→『総選択』
p.200 リスト5.16の6行目
『_Generic((X, Y), ...』→『_Generic((Y), ...』_Generic() の総称選択に使える値は1個だけです。(X, Y) としても、カンマ演算子(逐次評価)によって X が無視されて Y のみが使われるので、コンパイラによっては警告されます。X,Y のペアで判定されているかと誤解させそうな表記 (X,Y) はやめておくべきでしょう。
p.211 中央あたりの太字部分
『(global valiable)』→『(global variable)』

6章

p.236 下から7行目
『オプション(-lm)をつけてコンパイルする必要があります。』→『オプション(-lm)の必要な場合があります。』
Cygwin のように、gcc でも -lm の不要な環境があります。
p.238 中央の数式
分散の式の最後から2番目の項がおかしいようです。(式変形を追いかけきれません。)また最後の項は(間違いではありませんが)、カッコの位置を次のように移動したほうが、次のページのプログラムの動作に近くなります。(あるいは、カッコをなくすのもよいでしょう。)
var.png
p.249 上から2行目
『動的に配列サイズを変更することができるのです。』→『条件が揃えば動的に配列サイズを変更することができるのです。』C99準拠のコンパイラで、しかもローカル変数の場合に限られます。C11ではオプション機能に格下げになりましたし、C++ではサポートされていない機能です。要素数はマクロ定数にしておくのが基本だと理解してください。
p.263 上から(ソースコードを含めて)10行目
『/* Case2 */ int a[3][2] = {1,2,3,4,5,6}; と定義することもできます。』→『int a[3][2] = {1,2,3,4,5,6}; という記述はエラーにはなりませんが、「初期化子の周りに中括弧がありません」といった警告が出ることがあります。』

7章

p.273 リスト7.5 08行目
『2261』→『2265』2ヶ所あります。ハートマークの線画(♡)か塗りつぶし(♥)かの違いですが、下の実行結果と食い違っています。
p.274 本文の2行目
『1行といっても、その行の最後の改行(\n)は \0 に置き換えられて message に代入されます。』→『(削除)』この置換えをするのは gets です。fgets は置き換えを行いません。
p.283 Coffe Break 7.2
strcpy_s() や strcat_s() は C11 で導入された関数ですが、オプショナル機能と位置づけられているため、例えば gcc では使えません。

8章

p.295~297 リスト8.3, 8.4, 8.5
sizeof(int) の値を printf() で表示するためには "%zd" の書式指定子を使うか、値を(int)でキャストする必要があります。
p.298 リスト8.6の11行目から13行目
『%d』→『%td』ポインタどうしの減算の結果は ptrdiff_t 型になり、この値を表示するためには "%td" の書式指定子を使うか、あるいは値を(int)でキャストする必要があります。
p.301 リスト8.9の6行目
『int i;』は不要です。
p.309 リスト8.14の7行目
『 %s\n" 』→『 "%s\n" 』最初のダブルコーテーション(")が抜けています。

9章

p.317 2段落目からp.318 2行目
『また、構造体タグの省略について...警告を出すコンパイラも存在します。』→構造体タグを省略すると、その構造体を他の場面で利用できなくなるので、単独では(ほぼ)省略しません。後述の9.5.1節(p.339)のように、typedef と組合せて型名を付ける場合に(ほぼ)省略します。
p.320 リスト9.1
構造体がmain関数内で宣言されていますが(しかも変数定義を同時に行なっていますが)、こうするとこの構造体は通用範囲がmain関数に限定されてしまい、他の関数で用いることができませんので、このような使い方はしません。通常は複数の関数で扱えるように、構造体の宣言は関数の外側(特にプロトタイプ宣言の直前)に記述します。そして変数定義は分離することになります。
p.335 リスト9.5の41行目
初期化されない可能性があるため、コンパイラによっては警告されます。8行目の構造体変数max_dis_seat[]を、定義と同時に(0で)初期化するのが標準的な作法です。
p.338 ソースコード内の下から3行め(print_address()関数内)
printf("     zip:%l\n", addr.zip);→printf("     zip:%d\n", addr.zip);
p.340--345
論理型の変数名には、is_selected のように is + 形容詞(過去分詞)にする習慣があり、さらに is を省略する場合もあります。しかし、ここでは selected が laguage_t 型になっていて、紛らわしいです。この用例では受け身にする必要性は見出だせないので select のほうがよいでしょう。

10章

p.371 リスト10.7
18行目では「if ( (fp=fopen()) == NULL)」とNULLとの比較が記述してあるのに、25行目では『while (fgets(string, STRING_SIZE, fp))』とNULLとの比較が省略されていて、一貫性に欠けます。370ページの5行目には「fgets関数はNULLを返します」との記述があるので、『while (fgets(string, STRING_SIZE, fp) != NULL)』とNULLとの比較を明示するのがよいでしょう。
p.373 リスト10.8
『if (fp... 』→『if ((fp... 』3ヶ所のカッコ始まりが抜けています。
p.374 リスト10.9
『if (fp... 』→『if ((fp... 』3ヶ所のカッコ始まりが抜けています。

11章

変数名や関数名の命名規則に、C言語では「すべて小文字、単語は_をはさんで連結する」というスネークケースが用いられるのが一般的ですが、「単語の先頭を大文字にして隙間なくつなげる」というキャメルケースや、大文字小文字の使い分けルールの読み取れない部分が残っています。(第2版よりは減りました。)スネークケースで統一されるよう、変数名は以下のように読み替えるのがよいでしょう。

383ページ
『MonthlyRecord_t』→『monthly_record_t』
『DailyRecord_t』→『daily_record_t』
また、このように typedef と組み合わせる場合、構造体にタグ名(MonthlyRecord_T や DailyRecord_T)をつける必要はありません。
387ページ
『MonthlyRecord_t』→『monthly_record_t』
『dayCount』→『day_count』
『dataFile』→『data_file』
他にも多数あります。

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS