警告是什么以及如何解决:格式‘%p’需要类型为‘void *’的参数,但打印出来时参数 2 的类型为‘int *’[-Wformat=]
What is and how to solve the warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] when printing it out
我有以下代码:
#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;
}
使用 GCC 编译此代码并使用 %p
打印出地址的值会给出以下警告:
01.c: In function ‘main’:
01.c:7:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", array);
~^ ~~~~~
%ls
01.c:8:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", p);
~^ ~
%ls
01.c:9:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &array[0]);
~^ ~~~~~~~~~
%ls
01.c:10:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &p[0]);
~^ ~~~~~
%ls
01.c:11:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n",
&(*array));
~^ ~~~~~~~~~
%ls ```
我该如何解决它们以及它们为什么会发生?另外,什么是%ls
?
它需要另一种类型的指针。您需要将其转换为 void *
printf("%p\n", array);
=> printf("%p\n", (void *)array);
任何类型的对象指针都可以隐式转换为 void *
而无需强制转换,反之亦然。
但是,printf
的 %p
格式说明符明确需要一个 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 *
具有相同的表示形式。然而,这在一般情况下不一定是正确的,并且无法转换可能会导致 undefined behavior 在不正确的系统上。
相比之下,调用下面的函数foo
不需要转换:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
因为编译时参数的类型是已知的。
我有以下代码:
#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;
}
使用 GCC 编译此代码并使用 %p
打印出地址的值会给出以下警告:
01.c: In function ‘main’: 01.c:7:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", array); ~^ ~~~~~ %ls 01.c:8:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", p); ~^ ~ %ls 01.c:9:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &array[0]); ~^ ~~~~~~~~~ %ls 01.c:10:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &p[0]); ~^ ~~~~~ %ls 01.c:11:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Wformat=] printf("%p\n", &(*array)); ~^ ~~~~~~~~~ %ls ```
我该如何解决它们以及它们为什么会发生?另外,什么是%ls
?
它需要另一种类型的指针。您需要将其转换为 void *
printf("%p\n", array);
=> printf("%p\n", (void *)array);
任何类型的对象指针都可以隐式转换为 void *
而无需强制转换,反之亦然。
但是,printf
的 %p
格式说明符明确需要一个 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 *
具有相同的表示形式。然而,这在一般情况下不一定是正确的,并且无法转换可能会导致 undefined behavior 在不正确的系统上。
相比之下,调用下面的函数foo
不需要转换:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
因为编译时参数的类型是已知的。