不常见的三指针输出

时间:2014-02-16 21:03:32

标签: c pointers

虽然我正在研究一个代码来掌握指针的使用,而且,分配双指针和三指针以查看发生了什么,我想出了这个结果。这是代码:

#include <stdio.h>
#include <stdlib.h> 

int main (void) 
{

  struct entry 
  {
    int value ;
    struct entry *next ;
  } ;

  struct entry n1, n2, n3 ;

 struct entry* Ptr1 ;
 struct entry* *Ptr2 ;
 struct entry* **Ptr3 ;

 n1.value = 100 ;
 n2.value = 200 ;
 n3.value = 300 ;

 Ptr1 = &n1 ;      /* Ptr1 points to entry n1 */

 Ptr1 = &n3 ;      /* Ptr1 now points to n2 */

 Ptr2 = &Ptr1 ;    /* Ptr2 points to where pointer Ptr points, i.e the entry n3 */

 Ptr3 = &Ptr2 ;    /* Moreover, Ptr3 points to where pointer Ptr2 does. */


 printf("\n The value of where Ptr1 points is : %d,\n The address of Ptr1 is : %d \n" , *Ptr1, Ptr1) ;
 printf("\n The value of where Ptr2 points is : %d,\n The address of Ptr2 is : %d \n", **Ptr2, Ptr2) ;
 printf("\n The value of where Ptr3 points is : %d,\n The address of Ptr3 is : %d \n", ***Ptr3,Ptr3) ; 

 printf("\n") ;

 printf(" The value of where Ptr2 points is : %d ,\n The value of where Ptr3 points is : %d ", **Ptr2, ***Ptr3 ) ;      

  system("pause") ;

 }

这是我的输出:

    The value of where Ptr1 points is : 300
    The address of Ptr1 is :-858993460

    The value of where Ptr2 points is : 300
    The address of Ptr2 is :-858993460

    The value of where Ptr3 points is : 300
    The address of Ptr3 is :-858993460

在单行中,我只打印Ptr2和Ptr3所指的值,我得到了这个:

  The value of Ptr2 is : 300
  The value of Ptr3 is : -858993460

我不明白。是不是应该在一次打印中打印相同的结果?我错过了什么吗?

先谢谢。

1 个答案:

答案 0 :(得分:2)

您每次发送给printf的第二个值都是错误的。这是因为您将整个结构传递给printf,而不仅仅是整数。我可以详细讨论这个问题(我在下面做了一些分析),但只知道printf是一个可变函数,而变量函数在C中非常挑剔。

实际发生的是,当您将整个条目结构作为第一个参数传递时,您将整个条目结构复制到堆栈中。作为参考,结构的大小为8个字节(嗯,出于教学目的)。

函数的可变参数(如printf)被视为堆栈上的一堆字节。因此,当您要求printf中的第一个整数(使用%d说明符)时,它会从堆栈中取出前4个字节。这些是你的结构的前4个字节,恰好是第一个成员,你的value

当您使用另一个%d请求接下来的4个字节时,结果是结构中未初始化的指针next的值。一些编译器,如Visual Studio,喜欢初始化值为0xCCCCCCCC的指针,以显示它们尚未设置。在十进制中,这是-858993460。 每次调用printf时,此未初始化的指针都是第二个打印的整数。由于结构的大小,如果要在任何printf中打印另一个整数声明,你会得到你想要的实际地址。

因此,对于解决方案,只需打印结构的值成员:

printf("\n The value of where Ptr1 points is : %d,\n The address of Ptr1 is : %d \n" , Ptr1->value, Ptr1) ;
printf("\n The value of where Ptr2 points is : %d,\n The address of Ptr2 is : %d \n", *Ptr2->value, Ptr2) ;
printf("\n The value of where Ptr3 points is : %d,\n The address of Ptr3 is : %d \n", **Ptr3->value,Ptr3) ; 

所以你的问题实际上不是双指针或三指针,只是有一些奇怪的C函数。

请注意,如果您使用*运算符,则需要少一个解除引用运算符->

请注意实际传入printf的内容。