C 什么是警告以及如何解决警告:格式‘;%p’;应为类型为‘;无效*’;,但参数2的类型为‘;int*’;[-Wformat=]打印时
我有以下代码:C 什么是警告以及如何解决警告:格式‘;%p’;应为类型为‘;无效*’;,但参数2的类型为‘;int*’;[-Wformat=]打印时,c,compiler-warnings,C,Compiler Warnings,我有以下代码: #include<stdio.h> int main(void){ int array[5]={10,20,30,40,50}; int *p; p=array; printf("%p\n", array); printf("%p\n", p); printf("%p\n", &array[0]); printf("%p\n", &p[0]); printf("%p\n", &(*array)); ret
#include<stdio.h>
int main(void){
int array[5]={10,20,30,40,50};
int *p;
p=array;
printf("%p\n", array);
printf("%p\n", p);
printf("%p\n", &array[0]);
printf("%p\n", &p[0]);
printf("%p\n", &(*array));
return 0;
}
我如何解决这些问题,以及为什么会发生这些问题?另外,什么是
%ls
?它需要另一种类型的指针。您需要将其强制转换为void*
printf(“%p\n”,数组)代码>=>printf(“%p\n”,(void*)数组)
任何类型的对象指针都可以在不强制转换的情况下隐式转换为void*
,反之亦然
但是,%p
格式说明符toprintf
显式地需要一个void*
参数,并且由于printf
是一个可变函数,因此不会发生隐式转换
当需要显式转换为void*
时,这是极少数情况之一:
printf("%p\n", (void *)array);
printf("%p\n", (void *)p);
printf("%p\n", (void *)&array[0]);
printf("%p\n", (void *)&p[0]);
printf("%p\n", (void *)&(*array));
在您可能接触到的大多数实现中,对象指针和void*
具有相同的表示形式。然而,通常情况下,这并不一定是正确的,如果不进行强制转换,可能会在不正确的系统上导致错误
相反,调用下面的函数foo
不需要强制转换:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
因为参数的类型在编译时是已知的。“%ls”
来自于编译器认为您可能正在尝试宽字符串打印。在这种情况下,OP可能应该忽略下行表决。许多这样的问题和答案示例在没有演员阵容的情况下错误地使用了%p
,许多问题和答案示例忽略了警告。感谢您@DuarteArribas认真对待警告。@exnihilo是的,我尝试打开所有我能打开的警告,所以我的代码是最好的。一个有用的模型是认为int*
,float*
,struct foo*
,还有许多人可以使用不同的指针大小和编码来引用不同的内存位置,然而void*
可以代表所有。因此,假设发送一个2字节的int*
到printf()
和printf()
期望一个4字节的void*
是一个问题。好吧,这是有道理的,所以最佳实践是,每次我使用%p
时,我应该将它转换为void*
?@Duartearriba是正确的,在使用%p
时总是转换为void*
我解释说:%p
需要void*
@p\uu J\uuu--“您需要将其强制转换为void*
”并不是一个真正的解释;标准要求它可能是一个更好的开始。
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}