C言語関係掲示板

過去ログ

No.219.printfで1バイト整数を表示するには?


No.1353

printfで1バイト整数を表示するには?
投稿者---しゅう(2002/03/30 00:52:31)


またよろしくお願いします。

2バイト整数は"%hd"と"%hu"、4バイト整数は"%ld"と"%lu"、8バイト整数は"%lld"と"%llu"だと記憶しています。
では1バイト整数はどうしたらいいのでしょうか?

あと、16進数の場合は"%02X"などとしておけば自動的に1バイトと解釈してくれるのでしょうか?


No.1358

Re:printfで1バイト整数を表示するには?
投稿者---kikk(2002/03/31 01:59:02)



ども。


>2バイト整数は"%hd"と"%hu"、4バイト整数は"%ld"と"%lu"、8バイト整数は"%lld"と"%llu"だと記憶しています。

実際の最近の処理系の実装はそうなっている可能性が高いですが、正確には、
hはshort、lはlong、llはlong longの整数を、符号付き10進数[d]/符号なし
10進数[u]で表示するための書式指定子です。なお、(long longの導入に
ともなって)llはC99から正式に導入されました。hは処理系独自の仕様だった
ような気がします(たぶん)。


>では1バイト整数はどうしたらいいのでしょうか?

C言語には純粋なバイト型(8ビット整数)は存在しません。で、普通は(バイト型
は多くの場合符号は不要なのでunsined)charを使うわけですが、1バイト整数を
8/10/16進数で表現するための書式指定子は用意されていません。

ところで。printf()のような可変個の引数をとる関数は、その引数をとにかく
引渡し用の領域に押し込めてから、順に取り出すというような仕組みになって
います。ところが、(可変個引数かどうかに関わらず)引数の引渡し時には引数の
型情報は引き渡されないので、何番目の引数がどういう型ないしサイズのもの
なのかがわからず、取り出すときに困ってしまいます。そのため、printf()や
scanf()では、1番目の引数の型を固定にしておいて、そこに2番目以降の型情報
(というかサイズ情報)と、出力(scanf()では入力)の方法(何進数とか、文字
として扱うといったようなこと)を指定するというアプローチをとっています。

さて。1バイト用書式指定子はないと書きましたが、現実にバイト型の代わりに
使われている(unsigned)charは、可変個の引数をとるprintf()の呼び出し時に
どうやって渡されているかという問題がでてきます。で、どうなってるかという
と、可変の部分の引数には型の格上げが適用されることになっていて、charと
shortはint、floatはdoubleとして扱われ(引き渡し用領域に押し込まれ)ます。
なので、char型の引数でも書式指定子にはintと同じものが指定できることに
なります。shortとintは(最近だとたぶん)長さが違うのに、どっちも%dで表示
できるのはこのためです。

したがって、

>あと、16進数の場合は"%02X"などとしておけば自動的に1バイトと解釈してくれるのでしょうか?

は、intに格上げされた後に、16進(大文字)で[X]、出力を2桁に制限し[2]、
短かったら0を出力[0]、というように解釈されます。結果だけみると「1バイト
と解釈」といえなくもないのですが。。

このへんの話は、C FAQの可変個引数の章も参考にしてみてください。


で、もとのタイトルの質問の回答としては、
・10進数ならintの時と同じ
・8,16進数なら2ないし02として表示するサイズを指定する
 (そうしないとintの長さ分だけ表示されてしまう)
ということになるでしょうか。


では。

No.1359

訂正
投稿者---kikk(2002/03/31 11:20:16)


ども。


間違いがあったので訂正します。

>hは処理系独自の仕様だったような気がします(たぶん)。

そんなことはなくてhも規格の範囲内です。


>・8,16進数なら2ないし02として表示するサイズを指定する
> (そうしないとintの長さ分だけ表示されてしまう)

そうしないと、のところは、1バイト整数に使う型に符号付文字型を選び、かつ、
intへの格上げ時に符号ビットの拡張が起こる処理系を使っている場合にこうなり
ます。あ、もうひとつ、格納されている値が負であるという条件もありますね。
# 厳密に言うと他にも可能性がありそうですが上記のは確実です

1番目の条件はコードの書き方でどうにかなりますが、2番目のほうはそういう
わけにはいきません。でも、まあ、たぶん、そうなっているとおもいます。


では。

No.1363

Re:printfで1バイト整数を表示するには?
投稿者---しゅう(2002/03/31 20:36:26)


引数のint未満はすべてintに格上げされるのは初めて知りました。
intが4バイトの系でもshortが%dで表示できるのは、CPUがリトルエンディアンだからたまたま
うまく表示できてるだけなんだと勝手に納得していたもので。(考えてみたら関係なさげ…)

とてもわかりやすかったです。
kikkさんありがとうございました。


No.1365

訂正の訂正
投稿者---kikk(2002/04/01 00:12:15)


ども。


># 厳密に言うと他にも可能性がありそうですが上記のは確実です

余計なことを考えすぎました。この部分は無視してください。


あと、可変個引数の格上げの話を書きましたが、K&RのC(ANSIのCがまとまる前のC)
にあった、引数は格上げされて渡される(こちらは一般の関数の引数引渡し時の話)
というのとは話が違うのでご注意あれ。


では。

戻る


「初心者のためのポイント学習C言語」 Last modified:2002.05.26
Copyright(c) 2000-2002 TOMOJI All Rights Reserved