関数printf()内の%lf


学生が書くC言語のプログラムに、「printf(“%lf”, x)」のような断片を見つけることがあります(ここでxはdoubleの変数)。

私:なんで%lfなの?
学生:doubleだからです。

確かにscanf系の関数では、代入先がfloatなら%f、doubleなら%lfを使います。しかし、printf系の関数の場合はそうではありません。対象がfloatでもdoubleでも%fを使います(正確に言えば、doubleには%fを使います。floatのための変換指定子はありませんが、%fを使えばfloatがdoubleにキャストされます)。

新・C言語入門 シニア編 (C言語実用マスターシリーズ) (単行本)

関数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.

2 thoughts on “関数printf()内の%lf

  1. 私もこの記事で知るまで、間違えていました。(×_×)
    でも、C99 で採用されたならもう間違いとは言えないのですかね?汗
    教える際には気をつけたいと思います。

  2. しおざわさん
    printf中の%lfは、「未定義」から「%fと同じ」になっただけなので、
    「doubleのために%lfを使うこと」は間違いだと思いますよ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>