ロベールのC++教室 (http://www7b.biglobe.ne.jp/~robe/cpphtml/mainmenu.html)
を読んでいて疑問に思ったことがあります。
printf関数を使っているようですが、
私は アドレスを表す書式指定フィールド を %p と習いましたが、
サイトでは %d と書かれています。
%p というのは間違いなのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
いいえ。%pで合ってます。
integer型とポインタ型の長さが等しいと分かっているときには、%dでも大丈夫です。
昔は%pとか無かったので、長さを確認した上で%dや%ldなどを使っていました。そのころの癖が抜けない人のコードではないでしょうか。
投稿2015/11/03 13:00
総合スコア86281
0
ベストアンサー
いえ、%pであっていますよ。
%pは頭に0xをつけて16進数で表示されると思います(0xがつくかどうかはライブラリによるみたいですけど)
%dは渡された値をint型とみなして10進数で表示します。
%dでポインタを表示するとint型とポインタ型のサイズが違う環境では正しい結果が出なくなります。
投稿2015/11/03 12:50
総合スコア2850
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
検証コード書いているうちにベストアンサー出ちゃったけど、ついでなので。
printf
の可変長部分は厳密な型チェックしてくれないのでポインタを無理矢理整数として解釈できてしまいます(賢いコンパイラは警告を出してあげますが、無視してコンパイルできます)。なので、ポインタをむりやりint
型と解釈して、%d
を使って出力しているのです。%p
を使わなかったのは、ポインタは本当にただの整数ですよってことを表したくて、整数として解釈した場合としたかったのではなかったのではないでしょうか。
で、サイトのコードには大きな問題があります。それはポインタのサイズとint
のサイズが同じとは限らないと言うことです。なので、そのコードではint
に収まらなかった分が切り捨てられた値が出力される場合があります。ではどうするかというと、C言語には必ずポインタのサイズ以上になるintptr_t
と言うのが用意されています。ということであらかじめintptr_t
型にキャストして置けば警告もでず、安心できます。でも、今度はprintfで問題があります。printf
にはintptr_t
のための%○
というのがありません。そこで、printf
等にintptr_t
を使うためのPRIdPTR
というマクロを使います。つまり、下のようなコードにすると警告も出ず、サイズ問題も解決したプログラムができあがります。
C++
1#include <stdio.h> 2#include <stdint.h> 3#include <inttypes.h> 4 5int main() 6{ 7 int a; 8 char b[10]; 9 printf("a : %" PRIdPTR "\nb : %" PRIdPTR "\nmain : %" PRIdPTR "\n", 10 (intptr_t)&a, (intptr_t)b, (intptr_t)main); 11 return 0; 12}
ただ、非常に残念なことにVisual StudioのC++コンパイラはPRIdPTR
等に対応していません。Visual Studioを使いたいのであれば、ポインタのサイズとint
, long
, long long
等のサイズを比較して適切な整数型を選ぶ必要があります。
投稿2015/11/03 13:38
総合スコア21741
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/11/03 13:04