30

プログラムが使用するメモリの量を出力するコードがあります。行は次のようになります。

printf("The about of RAM used is %u", anIntVariable*sizeof(double) );

ここで、anIntVariable は double 配列の要素数の int 変数です。いずれにせよ、32 ビット システムでは問題はありませんでしたが、64 ビット システムでは、符号なし long 整数に「%u」を使用することに関するコンパイラの警告が表示されます。形式コードとして "%lu" を使用すると、64 ビットの問題は修正されますが、型が unsigned int に戻るため、コンパイラは 32 ビットでエラーを発生させます。実際、sizeof(double) は 32 ビット システムと 64 ビット システムで異なる値を返すことがわかりました。コードを 32 ビットから 64 ビットに変換するための Web ページ ガイドをいくつか見つけました。

この行をプラットフォームに依存しない方法で記述するにはどうすればよいですか? プリプロセッサ ディレクティブを使用して実行できる方法はたくさんありますが、それはハックのようです。確かに、私が気づいていないエレガントな方法があります。

4

3 に答える 3

20

ポータブルprintf識別子は、インクルードファイルinttypes.hまたはここで提供されます。

このインクルードファイルには、特定のランタイム用の多くのポータブル識別子が含まれています。たとえば、PRIuPTRが必要です。これは、「ポインタのサイズまでのサイズで署名されたPRintfI識別子意味します。

その場合、例は次のようになります。

printf("The amount of RAM used is %" PRIuPTR, anIntVariable*sizeof(double) );

GCC 4.3を使用した64ビットLinuxでの結果(int anIntVariable = 1):

$ gcc test.c -m32 -o test && ./test
The amount of RAM used is 8
$ gcc test.c -o test && ./test
The amount of RAM used is 8

完全を期すために、接頭辞がSCNであるscanfの識別子もあります。

于 2009-09-10T02:35:14.253 に答える
14

sizeof の戻り値は size_t です。C99準拠のコンパイラを使用している場合は、これに使用できるようです。%zd%zu

D'oh: %zu(無署名) もちろんです。ありがとう、ワン。

于 2009-09-11T07:51:17.073 に答える
7

まず、「%」指定子を、印刷する実際のデータ型と一致させる必要があります。sizeofはデータ型size_tを返します。「%d」指定子を使用して float を出力しようとしてはならないのと同様に、「%u」や「%d」などで size_t を出力しようとしてはなりません。 size_t という意味ではありません。

他の返信では、新しいコンパイラ ("%z" および PRIu32) でこれを処理するためのいくつかの良い方法が示されていますが、以前は size_t を unsigned long にキャストし、"%lu" を使用して出力するだけでした。 :

printf("The amount of RAM used is %lu", (unsigned long)(anIntVariable*sizeof(double)) );

これは、 size_t が long よりも広いシステムでは機能しませんが、そのようなシステムは知りませんし、標準で許可されているかどうかもわかりません。

于 2009-09-11T08:09:44.670 に答える