【问题标题】:C how to print address as a decimal value (not hex) without compiler warningsC如何在没有编译器警告的情况下将地址打印为十进制值(不是十六进制)
【发布时间】:2021-04-21 17:04:24
【问题描述】:

我有一个int 指针,它指向另一个int 的地址。

当使用格式说明符 %p 打印指针时(正如 Stack Overflow 上的许多答案所建议的那样),它会以 十六进制 表示形式打印。

如何使用 十进制 表示形式打印指针的值?


代码示例

我发现可以使用this answer 中的%zu

int i = 1;
int *p = &i;
printf("Printing p: %%p = %p, %%zu = %zu\n", p, p);

当我使用 https://onlinegdb.com/EBienCIJnm 运行该代码时

  • 它实际上以十进制打印正确的值
  • 但是它也会输出一个编译器警告
warning: format ‘%zu’ expects argument of type ‘size_t’, but argument 3 has type ‘int *’ [-Wformat=]                                                                 
Printing p: %p = 0x7ffee623d8c4, %zu = 140732759529668

有没有办法以十进制表示 printf 指针的值,而不会出现编译器警告?

【问题讨论】:

  • unsigned long addr = (unsigned long)p; printf("Printing addr: %lu\n",addr);这有什么问题吗?
  • 是的,看起来 %lu(unsigned long) 的演员组合也可以正常工作 (onlinegdb.com/OpOSsz6Oq)。我也喜欢它,因为它不像其他答案那样需要<stdint.h> 和/或<inttypes.h>#include。 @IrAM,这是一个独立于平台的解决方案(因为它需要指针的大小为unsigned long)?好像来自this Quora answer,并不总是unsigned long的大小
  • 我不是 100% 确定可移植性,但我的想法是根据平台选择可用的最长类型,以便您可以正确地表示十进制地址。我想任何平台都可以关注short <= int <= long <= long long

标签: c pointers printf memory-address format-string


【解决方案1】:

转换为<stdint.h> 中定义的uintptr_t 类型并使用<inttypes.h> 中定义的PRIuPTR 说明符进行格式化:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("%" PRIuPTR "\n", (uintptr_t) &argc);
}

【讨论】:

  • 这个C是哪个版本的PRIuPTR介绍的?
  • @IrAM:上个千年,C 1999。
  • 哦,我是最近才知道的!!! uintptr_t 是否为指针提供正确的值取决于平台,使其成为可移植的解决方案?
  • @IrAM:什么是“正确值”?它非常便携。实现提供uintptr_t 是可选的,但大多数C 实现都提供,如果提供,则生成的uintptr_t 值包含表示指针所需的所有信息。如何将其编码为无符号整数是实现定义的,因此该方面是不可移植的。具有平面地址空间的实现通常将地址直接用于整数值。以十进制打印它有点不常见。地址通常以十六进制打印,您可以使用PRIxPTR
【解决方案2】:

将指针转换为uintmax_t(在&lt;stdint.h&gt; 中定义),并使用%ju 打印转换结果:

printf("Printing p: %%p = %p, %%ju = %ju\n", p, (uintmax_t)p);

请注意,不能保证uintmax_t 的宽度足以容纳一个指针,但它可能没问题。 (如果它不适合您的平台,编译器可能会抱怨。)您可以使用uintptr_t,正如其他地方所建议的那样,但如果uintmax_t 不够宽,uintptr_t 将根本不存在。

总的来说,你最好学习如何处理十六进制输出:-)

【讨论】:

    猜你喜欢
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 2014-09-18
    • 1970-01-01
    • 2013-03-31
    • 1970-01-01
    相关资源
    最近更新 更多