场合
考虑以下源代码,目的是打印两个a,即输出应该是" aa":
#include <stdio.h>
int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = (char*)a_pnt;
printf("%c", *(char*)a_pnt);
printf("%c", *b_pnt);// why is the compiler saying I am dereferencing a void pointer? It was already cast
return 0;
}
并发症
打印第一个&#34; a&#34;但是编译器在第10行(第二次打印&#34; a&#34;)上发出编译时错误说:
无效使用void表达式
并在同一行上发出警告说:
解除引用&#39;无效*&#39;指针
虽然b_pnt确实被声明为一个空指针,但是它被强制转换为第7行定义中的字符指针。我唯一的猜测就是为什么它的抱怨与我只能在引用时才能进行转换这一事实有关。同时。我的预感是基于第一个变量工作正常的事实。
解决方案
解决方案是声明并定义一个名为&#39; b&#39;的字符变量。并在打印前预先转换为字符指针:
#include <stdio.h>
int main ()
{
char a = 'a';
void* a_pnt = &a;
void* b_pnt = a_pnt;
char b = *((char*)b_pnt);
printf("%c", *(char*)a_pnt);
printf("%c", b);// why is the compiler saying I am dereferencing a pointer?
return 0;
}
问题仍然存在:为什么最初的尝试失败了?
我故意用void指针开始说明问题。确实可以完全避免使用正确的指针类型。
答案 0 :(得分:1)
仅仅因为您在分配给b_pnt
时执行了演员表并不意味着它的类型发生了变化。它的类型仍为void *
,并且取消引用它是一个错误。
您可以在没有警告的情况下自由地将任何非功能指针类型分配给void *
。但是编译器没有跟踪那里存储了什么类型的指针,因此它仍然是void *
,需要在它被解除引用之前进行转换。