在C中访问void双指针时,void指针如何正常工作?

问题描述 投票:-1回答:1

学习有关空指针的知识,并越过了该程序。在这里,我声明了void指针,并尝试访问void双指针,并且工作正常。这里无法理解C逻辑。有人可以帮忙吗?谢谢。

#include<stdio.h>
int main()
{
 int i = 5,*ptr;
 ptr= &i;
 void *vptr; 
 vptr = &ptr;
 printf("\nValue of iptr = %d %d %d", **(int **)vptr, **(int ***)vptr, **(int ****)vptr);
 return 0;
}

op:

Value of iptr = 5 5 5
c void-pointers
1个回答
-1
投票

这似乎很奇怪,但是从语言的角度来看是完全合法的,即使它以明显的方式表明了语言的某些局限性。在这种情况下,wrong强制转换将导致编译器未检测到UB,并给出错误的输出为有效。

您将vptr定义为指向void指针的指针,因此回头对其进行解引用,就可以得到指向值为5的int的指针。

然后在示例代码中,您cast vptr成为指向指针的指针……等等,但是您仅打印第二次取消引用,恰好是找到的值:5您解释为整数

实际上,编译器正在显示所谓的第二指针值,并将值5解释为地址。

编译器还应该发出有关printf中类型不匹配的警告(您应该将%p与指针一起使用。

如果您尝试更多的取消引用,将出现预期的访问冲突。

尝试

 printf("\nValue of iptr = %d", ***(int ***)vptr);

在第二次取消引用之后,您尝试在内存地址0x00000005读取。

注意:应用强制转换,除非对于不兼容的类型,否则您将[[impose”提交给编译器,以将强制转换对象视为强制转换类型的对象。该语言不会执行任何检查,并且会盲目遵循您的指示。如果您告诉编译器在该位置期望一个指针,则它将根据实际位置独立地期望一个指针。


-1
投票
那是因为您在函数中按值传递参数。我将通过以下示例进行说明:

int a = 10; int* p = &a; printf("%d", p); // <-- this will print the value of p which is the address of a. printf("%d", *p); // <-- this will print the value of a.

在您的情况下,编译器可能会发出警告,告诉您%d期望类型为int,但被赋予类型为int*

第一次调用printf将使第二个参数作为int**(int**)vptr)传递。所以这里没有错。

第二个调用将把第二个参数作为int*传递,但是,正如我在上面的示例中所解释的,当您传递一个指针时,您传递了它的值。您可以这样看:

printf("%d", (int*) (**(int**)vptr) );

"%d"printf需要一种int类型,因此,即使您具有printf("%d", (int*)5),它仍会打印5

实际上,您可以给它任何类型,并且仍将其视为int。您可以拨打以下电话:

printf("%d", (int**) 10 ); printf("%d", (char*) 10 ); printf("%d", (float*) 10 ); printf("%d", (void*) 10 ); // ... and so on

上述所有呼叫将打印10,对于与int具有相同大小的所有类型,将打印10。
© www.soinside.com 2019 - 2024. All rights reserved.