学生が書くC言語のプログラムに、「printf(“%lf”, x)」のような断片を見つけることがあります(ここでxはdoubleの変数)。
私:なんで%lfなの?
学生:doubleだからです。
確かにscanf系の関数では、代入先がfloatなら%f、doubleなら%lfを使います。しかし、printf系の関数の場合はそうではありません。対象がfloatでもdoubleでも%fを使います(正確に言えば、doubleには%fを使います。floatのための変換指定子はありませんが、%fを使えばfloatがdoubleにキャストされます)。
関数printf()の変換修飾子「l」の意味は次の通りです。
変換指定子がd、i、o、u、x、Xのとき対応する引数がlong型またはunsigned long型であることを示す。変換指定子がnのとき対応する引数がlong型へのポインタであることを示す。(『新訂新C言語入門シニア編』p.321)
変換指定子「f」に変換修飾子「l」は付かないのです。関数printf()内の%lfは、C90では未定義です。
間違って書く人が多かったためか、C99では%lfを使うことが許容されました。%fとして扱うというだけのことですが。
単純に「floatは%f、doubleは%lf」と憶えておけばよいことになったのですから、学生にとってはいい話かもしれません。しかし、こんな間違った憶え方をする前に、「どのように動いているのか」を考える癖をつけたほうがいいのではないでしょうか。
Javaでも1.5からprintfが使えるようになりましたが、”%lf”と書くと例外が発生します。
年配の先生から「使い分けなければならないハードもかつてはあった」ということを教えてもらいました。
No related posts.

私もこの記事で知るまで、間違えていました。(×_×)
でも、C99 で採用されたならもう間違いとは言えないのですかね?汗
教える際には気をつけたいと思います。
しおざわさん
printf中の%lfは、「未定義」から「%fと同じ」になっただけなので、
「doubleのために%lfを使うこと」は間違いだと思いますよ。