「ドリル&ゼミナールC言語」(毎日コミュニケーションズ発行)の内容への補足事項をまとめました。なお、正誤表はこちらになります。
2003.06.06作成
解説図入りの詳しい設定方法のページをご用意しました。
(誤)LSI C C-86
(正)LSI C-86
※ 登録商標を誤記するなどあってはならないミスです。この失態を恥じるとともに深く反省しております。
・先頭から最低31文字までが有効である。
※ どの処理系を用いても最低31文字までが有効で、それ以上の文字数が有効になる処理系もあるという意味です。
2003.07.27追加
(誤)10.zを倍精度実数型で宣言
(正)10.zを倍精度浮動小数点型で宣言
※ 実数型=浮動小数点型 なのですが、本書では浮動小数点型で記述を統一しているので、ここは「浮動小数点型」とすべきでした。(修正依頼は出していたのですが…。)
この演習は、いろいろな型の宣言を使ってみましょう、という趣旨の問題なのですが、
13. b = 23.3;の部分で、コンパイラのチェックが厳しいと、警告が出ます。
小数点が付いている定数はコンパイラがdouble型であると判断するのですが、double型の定数をfloat型の変数に代入しようとしているので、精度の高いdouble型から精度の低いfloat型に代入してもいいですか、と警告を発するわけです。
一方、
12. a = 62.5;の場合は警告が出ません。62.5 という数値は2進数に変換した場合に誤差を生じないのです。ですから、精度の小さなfloat型変数aに代入しても誤差が大きくなると言うことはなく、警告を発しません。けれども、23.3 の方は2進数に変換すると誤差が生じます。ですから、double型よりも精度の小さなfloat型に代入すると誤差が大きくなるので警告を発するコンパイラがあるのです。
23.3の方も警告を出さないようにするには、「23.3F」のように、float型定数として記述します。この場合は、float型定数をfloat型変数に代入することになり、警告は出ません。
なお、この件につきましては、p.282「浮動小数点数と誤差」で詳しく説明していますので、ご参照ください。
2004.04.02追加
(誤)「\'」のようにエスケープシーケンスで示します。
(正)「\'」のように拡張表記で示します。
※ エスケープシーケンス=拡張表記 なのですが、本書ではJIS規格の拡張表記で記述を統一しているので、ここは「拡張表記」とすべきでした。(修正依頼は出していたのですが…。)
このプログラムの入力は
9abcdeではなく、
9 a b c d eになります。つまりそれぞれにスペースが入りますので、ご注意ください。
もし、「9abcde」と入力した場合には、実行結果は次のようになります。
「9abcde」と入力
r = 0 n1 = 0, n2 = 0 r = 1 n1 = 9, n2 = 0再び「9abcde」と入力
r = 2 n1 = 703710, n2 = 10140894この場合は、最初の"%o%o"では何も入力できず、次の"%d%d"では9のみ入力し、最後の"%x%x"では"abcde"(10進数の703710)と"9abcde"(10進数の10140894)が入力されます。
2004.04.02追加
「これらの例を処理したい場合には、if文を用いるようにしてください。」とありますが、文字列の場合には、更にstrcmp関数を用いる必要があります。
この図を見て、変数の宣言は a,b の順で行っているのに、図では何故 b が上で a が下なのかと不思議に思う方もいるかもしれませんね。
P260 の「図6-2-3」を見ていただければわかるのですが、ローカル変数の場合(P198 の変数 aと b はローカル変数に該当します)、メモリ上のスタック領域に宣言された順に積まれるので、b が上で a が下になります。
(誤)24.rcに0を初期値として代入
(正)24.rcを0で初期化
※ 「初期化」と「代入」は明確に区別しなければならないので、ここは「初期化」にすべきでした。
原稿には次の図があったのですが、スペースの関係で割愛しました。
(誤)26.forループのブロック内でnoを宣言しi*5を代入
(正)26.forループのブロック内でnoを宣言しi*5で初期化
※ 「初期化」と「代入」は明確に区別しなければならないので、ここは「初期化」にすべきでした。
LSI C-86 Ver3.30c試食版を用いて、このソースをコンパイルすると
19:警告:tempの値が未定義という警告が生じます。122.c の場合、scanf で、temp の各メンバに値が設定されるので、temp 自体は値が設定されているはずなのですが、LSI C-86 がそれを認識できずに警告を発します。つまり、122.c に問題があるわけではありません。
2003.07.27追加
#define power3(x) ((x) * (x)) のときに、
power3(++a); は
((++a) * (++a)) と展開されるのですが、式をどのように計算するかは処理系依存になります。
((6) * (6)) と計算する処理系も、((6) * (7)) と計算する処理系も、((7) * (6)) と計算する処理系も、((7) * (7)) と計算する処理系もあります。
よって、実行結果は処理系によって異なる場合があります。
そもそも、このマクロ展開のように、ひとつの式の中で同じ変数を複数回変更することは行ってはいけません。詳しくは、C FAQ 3.2 をご参照ください。
2003.07.15追加
(誤)""で囲まれたヘッダファイルの場合は、一般にコンパイラはまず現在作業中のカレントディレクトリを探索に行きます。
(正)""で囲まれたヘッダファイルの場合は、一般にコンパイラはまずコンパイルするソースファイルのあるディレクトリを探索に行きます。
※ これは不適切な記述でした。カレントディレクトリをソースファイルのあるディレクトリとは別のディレクトリに移動し、そのカレントディレクトリとソースファイルのあるディレクトリの両方に同じ名前で内容の異なるヘッダファイルを用意し、ソースファイルでそのヘッダファイルをインクルードした場合、インクルードされるのはソースファイルと同じディレクトリにあるヘッダファイルです。
編集の都合で上記のように記述上の不統一な箇所があります。大変にお手数をお掛けし申し訳ありませんが、ご不明な点は、本書の8ページに記されているURLよりソースファイルをダウンロードしてご確認くださるようにお願いいたします。
2003.07.27追加
お気づきの点は下記へご連絡をお願いします。 sgwr-t@sea.plala.or.jp |
▲▲戻る▲▲
「ドリル&ゼミナールC言語」 毎日コミュニケーションズ発行 ISBN 4-8399-1077-4