【问题标题】:Why is a pointer cast as (void*)p when used in printf? [duplicate]为什么在 printf 中使用指针转换为 (void*)p? [复制]
【发布时间】:2019-07-03 00:44:42
【问题描述】:
char  x = 'G';
char *p = &x;

printf ("Address of x: %p\n", p);
printf ("Address of x: %p\n", (void*)p);

谁能告诉我(void*)p 到底是什么意思?我知道它和p一样,因为那也给了我x的地址,但是为什么写成(void*)p

【问题讨论】:

  • %p 说明符要求 void* 作为参数传递。 (void*)p 正在将 p 投射到此类。
  • @paulsm4 恐怕纯标题贡献了。我已经编辑了标题(并撤回了反对票)。一方面,我不知道 %p 需要 void 指针。
  • 谢谢你,苏玛。另一个潜在的重复是:printf("%p") and casting to (void *)
  • 在我学会用 C 编程的机器上(回到 C 标准还没有出现的时代——在 void *%p 存在之前),如果你打印short s; printf("0x%lX\n", &s); printf("0x%lX\n", (char *)&s);,你会得到不同的结果,因为机器使用了面向字的寻址。与同一对象的char * 地址相比,任何“比char 更宽”的类型都是如此。这意味着您必须非常小心,以确保在使用 malloc() 之前声明它,否则一切都会可怕地爆炸。这些天来,它更容易了。
  • @chux: C11 §6.2.5 Types ¶28 说:指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。48) 脚注 48 说:相同的表示和对齐要求意味着作为函数的参数、函数的返回值和联合成员的可互换性。我认为它们在所有情况下都必须是等效的,包括@987654338 @ — 但只是在参数列表的 ... 部分写入 0 并不一定会创建指针大小的值;使用演员表。

标签: c


【解决方案1】:

C 标准对 printf 系列函数的 %p 格式说明符进行了说明(第 7.21.6.2 节,第 12 段)

对应的参数应该是一个指向void的指针。

指向不同类型的指针的内部表示可能不同,void *char * 指针除外,它们保证大小相同。但是,任何对象指针类型都可以转换为void *。因此,为了确保所有%p 变量都被printf 正确处理,它们必须是void *

【讨论】:

  • 关于“除了”:所有指向结构类型的指针都应具有彼此相同的表示和对齐要求(但可能与 void *char * 不同),根据 C 2018 6.2。 5 28. 和联合指针是一样的。并且指向兼容类型的合格或不合格版本的指针彼此相同。
猜你喜欢
  • 1970-01-01
  • 2014-09-12
  • 2013-06-03
  • 2023-04-11
  • 1970-01-01
  • 2013-06-05
  • 2014-10-22
  • 2016-08-07
相关资源
最近更新 更多