【问题标题】:Whats the difference between printf("%d","%u","%p",ptr,ptr,ptr) and printf("%d %u %p",ptr,ptr,ptr)?printf("%d","%u","%p",ptr,ptr,ptr) 和 printf("%d %u %p",ptr,ptr,ptr) 有什么区别?
【发布时间】:2019-06-23 05:45:02
【问题描述】:

当我尝试 printf("%p","%d","%u",ptr,ptr,ptr) 我得到 00405067 但是当我尝试执行 printf("%p %d %u",ptr, ptr,ptr) 我分别得到 0061FF28 6422312 6422312。后半部分我懂,但前半部分不太清楚。

int main()
{
    int  a = 1;
    int *ptr;
    ptr = &a;
    printf("%p","%d","%u",ptr,ptr,ptr);
    return 0;
}
Output: 00405067
________________

int main()
{
    int  a = 1;
    int *ptr;
    ptr = &a;
    printf("%p %d %u",ptr,ptr,ptr);
    return 0;
}
Output: 0061FF28 6422312 6422312

【问题讨论】:

  • 前者从何而来?这是完全错误的。
  • 第一个参数是决定打印什么的格式字符串。一个告诉 printf 打印一个值另外三个。
  • 我使用代码块,这就是我得到的:/
  • 它们都是未定义的行为,所以技术上是一样的

标签: c pointers printf


【解决方案1】:

printf("%p","%d","%u",ptr,ptr,ptr)

格式字符串就是"%p"。它打印一个指针,即"%d"(字符串文字)的地址。其余参数 ("%u", ptr, ptr, ptr) 在格式字符串中没有相应的指令,因此它们被忽略了。

调用实际上等同于

printf("%p", "...");

请注意,%p 采用 void *,而 %d 采用 int%u 采用 unsigned int。如果要打印指针的值,正确的解决方案是使用%p,并将指针强制转换为(void *),如

printf("%p\n", (void *)ptr);

要将指针格式化为整数,我相信唯一 100% 可移植的解决方案是

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

...
printf("%" PRIuPTR "\n", (uintptr_t)(void *)ptr);

【讨论】:

  • “将指针格式化为整数 .... 只有 100% 可移植的解决方案”有 2 个不可移植的方面。罕见的 C99 或更高版本的编译器可能没有 optional 类型 (u)intptr_t。当ptr 是对象指针而不是函数指针时,(void *)ptr 的定义就很好。
  • @chux 我的想法是,实现可能不提供这种类型的唯一原因是它根本不支持将指针转换为整数。否则添加typedef 不会花费任何费用。此外,如果您遇到这种情况,它会在编译时提前彻底失败。
猜你喜欢
  • 2023-04-11
  • 1970-01-01
  • 2019-12-12
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 2013-01-16
  • 1970-01-01
相关资源
最近更新 更多