我有以下代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
使用 GCC 编译此代码并打印出地址的值%p会给出以下警告:
Run Code Online (Sandbox Code Playgroud)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 *不进行强制转换的情况下隐式转换为 a ,反之亦然。
但是,%p格式说明符printf显式需要一个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));
Run Code Online (Sandbox Code Playgroud)
在大多数实现中,您可能会接触到对象指针并void *具有相同的表示形式。然而,这在一般情况下不一定是正确的,并且未能强制转换可能会导致系统上的未定义行为,而这并非如此。
相比之下,调用foo下面的函数不需要强制转换:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
Run Code Online (Sandbox Code Playgroud)
因为参数的类型在编译时是已知的。
| 归档时间: |
|
| 查看次数: |
427 次 |
| 最近记录: |