30

我有一些代码可以打印程序使用的内存量。该行与此类似:

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

其中 anIntVariable 是双精度数组元素数量的 int 变量。无论如何,在 32 位系统上我从来没有遇到过任何问题,但在 64 位系统上,我收到一个编译器警告,提示我将“%u”用于无符号长整数。使用“%lu”作为格式代码修复了 64 位上的问题,但会导致编译器在 32 位上报错,因为类型恢复为 unsigned int。我发现,确实,sizeof(double) 在 32 位和 64 位系统上返回不同的值。我找到了一些网页指南,可以代码从 32 位转换为 64 位,但我更希望代码可以同时在两者上运行,而不仅仅是来回转换。

如何以独立于平台的方式编写此行?我知道很多方法可以使用预处理器指令来做到这一点,但这似乎是一种 hack。当然,我没有意识到一种优雅的方式。

4

3 回答 3

20

可移植的 printf 标识符在包含文件inttypes.h此处提供。

此包含文件具有许多适用于您的特定运行时的可移植标识符。对于您的示例,您需要 PRIuPTR,这意味着“ PR intf I标识符签名,大小不超过指针大小”。

您的示例将是:

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

为了完整起见,scanf 也有标识符,其前缀是 SCN。

于 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" 说明符打印浮点数一样,您也不应该尝试使用 "%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 回答