2016-04-11 45 views
3

我很难理解这段代码是如何工作的。我一直认为在使用指针结构之前,应该定义它。在下面的例子中,为什么编译器不会抱怨struct LL * Next?在定义结构之前如何使用指向结构的指针?

typedef struct LL 
{ 
    int value; 
    **struct LL* Next;** 
}Node; 

Node* temp; 
+0

不太清楚你想问什么。你问为什么'struct LL * Next;'不是错误? –

+0

是@SouravGhosh –

+0

您显示的代码不使用任何未初始化的指针。 –

回答

5

在你的代码,

struct LL* Next; 

被允许作为struct LL定义本身内部的成员,并不会引发任何错误,因为,在这一点上,编译器不需要知道的定义结构本身。它只需要分配一个指向结构的指针,这样就可以。

稍后,在使用struct类型的变量时,必须为指针分配内存,并在进一步使用之前将该内存分配给指针。

+0

如果不使用术语*不完整类型*,则无法回答此问题。 – IInspectable

0

您可以在结构定义中使用不完整的类型(缺少足够的信息来确定该类型对象的大小)。当您在struct LL的定义中编写struct LL* Next;时,LL已被声明为结构,因此不会引发错误。

事实上,N1570已经提供了一些实施例关于这一点:

10实施例1个该机制允许自引用 结构的声明。

 struct tnode { 
      int count; 
      struct tnode *left, *right; 
     }; 

指定包含的整数,并且两个指针到同一类型的对象 的结构。 ......

11以下替代制剂使用的typedef机构:

 typedef struct tnode TNODE; 
     struct tnode { 
      int count; 
      TNODE *left, *right; 
     }; 
     TNODE s, *sp; 
-1

“的变量应该总是被初始化” 是经验法则。这不是一个很好的规则,有时(比如你的例子),它必须被违反,至少是暂时的。未初始化的数据(垃圾)不会自行产生问题。

一些程序员会像这样虔诚地初始化他们的变量。

int i = 0; 
Node * foo = NULL; 

没有什么强迫你这样做。这只是程序员做不必要的事情。

初始化你的指针之前有意义的东西虽然重要。

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

typedef struct LL 
{ 
    int value; 
    struct LL* next; 
}Node; 

int main (int argc, char ** argv) 
{ 
    Node * A; // OK. A points at garbage. 
    Node * B; // OK. B points at garbage. 
    B = A; // Dumb, but OK. B now points at the same garbage as A. 
    B = A->next; // ERROR. You can't dereference garbage. 
    A = malloc (sizeof(Node)); // A is no longer points at garbage. The newly created A->value and A->Next are garbage though. 
    B = A->next; // Dumb, but OK. B now points at the same garbage as A->Next. 
    B->value = 200; // ERROR. B is garbage, you can't dereference garbage. 
    A->value = 100; // OK. A->value was garbage, but is now 100. 

    // ********************************* 

    // Enough academic examples. Let's finish making the linked list. 
    A->next = malloc(sizeof(Node)); // OK. A->value no longer points at garbage. 
    B = A->next; // OK. B now points at the second node in the list. 
    B->value = 200; // OK. B->value was garbage, is now 200. 
    B->next = NULL; // OK. B->Next was garbage, is now NULL. 

    printf("A: %#x, value: %d, next: %#x\n", A, A->value, A->next); 
    printf("B: %#x, value: %d, next: %#x\n", B, B->value, B->next); 

    return 0; 
} 
+1

'Node * A;节点* B; B = A;'是UB。 – chux