【问题标题】:What does (void*) mean in context of typecasting? [duplicate](void*) 在类型转换的上下文中是什么意思? [复制]
【发布时间】:2018-04-22 15:43:40
【问题描述】:

以下代码中的 (void*) 是什么意思?我尝试删除 (void*) 类型转换,但它仍然可以正常工作并打印 usrInt 变量的地址。你能解释一下吗?

#include <stdio.h>

int main(void) {
   int usrInt = 0;    // User defined int value
   int* myPtr = NULL; // Pointer to the user defined int value

   // Prompt user for input
   printf("Enter any number: ");
   scanf("%d", &usrInt);

   // Output int value and location
   printf("We wrote your number into variable usrInt.\n");
   printf("The content of usrInt is: %d.\n", usrInt);
   printf("usrInt's memory address is: %p.\n", (void*) &usrInt);
   printf("\nWe can store that address into pointer variable myPtr.\n");

   // Grab location storing user value
   myPtr = &usrInt;

   // Output pointer value and value pointed by pointer
   printf("The content of myPtr is: %p.\n", (void*) myPtr);
   printf("The content of what myPtr points to is: %d.\n", *myPtr);

   return 0;
}

【问题讨论】:

  • %p 使用指向void 的指针。当不强制转换时,行为在技术上是未定义的。
  • 没有要求 void* 在内存中的大小与 int* 相同——现在很清楚为什么需要这样做以避免未定义的行为?

标签: c pointers void void-pointers


【解决方案1】:

通常,对void * 的强制转换只是多余的,因为对于任何数据指针类型,这种转换在 C 中都是隐式的。

将指针传递给 variadic 函数是需要强制转换的特殊情况。

printf() 是一个可变参数 函数。 printf() 原型如下所示:

int printf(const char *format, ...);

这意味着编译器看不到format 之后的参数的任何类型声明。因此,它不知道传递的类型应该是void *,所以转换不会自动发生。

通常,省略强制转换不会产生任何可见的效果,因为在大多数实现中,所有指针都具有完全相同的内部表示。 但 C 标准不保证这一点,因此在例如int * 在转换为 void * 时会有不同的表示形式。如果您省略强制转换,您的代码在技术上是不正确的(它调用 未定义的行为 为转换 %p 传递错误的类型),并且会在指向不同类型的指针表示的平台上导致错误的结果不一样。

【讨论】:

    【解决方案2】:

    c11:7.21.6 格式化输入/输出函数(p8):

    p - 参数应该是一个指向 void 的指针。指针的值以实现定义的方式转换为打印字符序列。

    【讨论】:

      猜你喜欢
      • 2019-12-08
      • 2014-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      • 2015-08-01
      • 2017-07-11
      • 2011-04-25
      • 2016-12-03
      相关资源
      最近更新 更多