为什么我必须将我的内存地址转换为(void *)?

时间:2016-08-06 03:42:47

标签: c

所以我现在只学习C大约3周了,我正在使用this教程来帮助我理解指针。

我写的一切都和他一样,但我正在使用Putty和Vim来编写我的代码。然而,当我编译我的代码时,它会说“警告:格式'%p'需要'void *'类型的参数”。为什么我必须在教程中强制转换为'void *'而不是?

int main()
{
    int tuna = 19;
    int *pTuna = &tuna;

    printf("Address \t Name \t Value \n");
    printf("%p \t %s \t %d \n", pTuna, "tuna", tuna);

    return 0;
}

我已将pTuna转换为“void *”并且程序编译并运行良好但我不明白为什么以及为什么在教程中不需要进行转换。

感谢您的回答!

3 个答案:

答案 0 :(得分:1)

编译器正在执行其主要作业之一,并且 typechecking 表示您要使用的值。 pTuna是指向int 的指针(例如int *),而%p格式说明符需要泛型(或{{1} })指针。

编译器发出关于类型不匹配的警告,告诉您再次查看该问题并提供将使用void *转换说明符的值的正确转换。您遵守:

%p

再次编译 - 警告消失了,编译器完成了它的工作,一切都很好。 (是的,您可以忽略警告,但如果警告和无错误编译不是绝对的个人要求,那可能值得添加。(是的,在某些情况下,警告可能是已知且不可避免的结果一些实现,但那些很少和很远。这里的这一个不是其中之一。

答案 1 :(得分:0)

可能是教程使用的是与您正在使用的编译器不同的编译器。

在这两种情况下,程序都会编译,但是编译器会发出警告,指出教程中使用的那个可能不会。

另一个选择是教程在编译时使用标志来禁止警告。一个例子是" -w" GCC中的标志禁止所有警告。

无论哪种方式,printf函数都需要" void *"有%p时的参数,所以你应该把它投出来。

答案 2 :(得分:-3)

它只是一个编译器警告。你应该第一次使用已编译的二进制文件。

编译器会抱怨类型是否匹配:%p期望void*,而参数类型为int*。在这种情况下,可以忽略警告,因为您只是打印指针的基地址而不是用它做任何其他事情。

也就是说,消除编译器警告通常是一种好习惯,因为它们可以帮助您进行检查。但是,在实践中,您可能无法清除所有内容,尤其是当您不拥有代码并且不想触摸它们时(例如图书馆)。

警告存在让你三思而后行,但仍会编译程序。