警告是什么以及如何解决:格式‘%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);
}

因为编译时参数的类型是已知的。