『C言語によるプログラミング―スーパーリファレンス編』は,Cプログラミングの講義を担当することが決まってから購入し,内容で気になったらいつも参照しています.
今年度から,この本を学科授業の教科書として,1年後期,2年前期のCプログラミング授業だけでなく,Cで何かを書くときに参照する本として,使っていく予定です.
なのですが,いくつか誤記があり,Amazonで最近購入した第1版第4刷(平成16年3月20日)でもそのままなので,ここで記載しておきます.授業を受ける学生のみなさんへ: 購入したら,鉛筆で加筆訂正しておいてください.
仮引数の不完全型配列変数
ちなみに不完全型のオブジェクトに対してsizeof演算子は適用できませんので,次のプログラムはエラーとなります.
double SumUp_1( double x[] ) { int k; int n=sizeof x/sizeof x[0]; double s=0.0; for( k = 0; k<n; k++ ) s += x[k]; return s; }(9.4.1 不完全型の配列, p.68)
「sizeof x」のところに,「xは不完全型なのでsizeof演算子は適用できないので,エラーとなる」と添え書きもあります.
この記述は丸ごと間違いです.すでに仮引数の配列変数は,ポインタなのか配列なのか - わさっきで述べ,私自身も勘違いがありましたが,関数の仮引数に書かれる配列型は,要素数を指定しても,「x[]」のように不完全型で指定していても,ポインタ変数になります.したがってコンパイル時点で,sizeof xを求めることができ,コンパイルエラーにはなりません.
ただし,文法的に問題ないことgrammatical correctnessと,プログラマの期待通り動作することとは別です.「sizeof x/sizeof x[0]」で,xの指す配列の要素数を求めることはできません.対策は,関数から見た配列のサイズは? - わさっきに挙げています.
strncpy
strncpy() (14.18節,p.520)の注意の中に,「コピー先文字列にはナル文字が付加されます」と書かれていますが,これは間違いです*2.正しくは「fmの文字列長がn以上の場合、コピー先文字列にはナル文字は付加されません。」です.http://www.linux.or.jp/JM/html/LDP_man-pages/man3/strcpy.3.htmlにあるとおりです*3.
関連して,
- 細かいことですが,すぐ上の「(n+1)バイト文字列を格納するのに」は,「nバイト文字列を格納するのに」です.
- strncat() (14.16節,p.518)の注意では明記されていませんが,「str2の文字列長がnバイト以上の場合、str1の示す文字列には、str2の文字列の先頭nバイトを付加し、さらにナル文字も付加します。」を書いておくほうがいいでしょう(参考: http://www.linux.or.jp/JM/html/LDP_man-pages/man3/strncat.3.html).
そういえばstrncpyは,2年後期の情報ネットワーク演習の中で苦渋をなめました.演習室のLinux環境では問題なく動き,TAが自分のCygwin環境で確認すると不具合となった原因が,このナル文字が付加されていなかったことだったのです.