2013-03-20 68 views
10

Tôi đang nghiên cứu các ví dụ mã từ giáo sư của mình để làm quen tốt hơn với các cấu trúc dữ liệu được liên kết.Mục đích của nút "đầu tiên" trong khai báo: "typedef struct node {- - -} Node;"?

Trong ví dụ liên kết-list.c chúng tôi giáo sư định nghĩa một loại Node như sau:

typedef struct node { 
    int data; 
    struct node *next; 
} Node; 

điểm của chữ thường nút là gì? Tôi đã có ấn tượng rằng bạn chỉ có thể viết, ví dụ:

typedef struct { 
    int data; 
    struct node *next; 
} Node; 

và sau đó sử dụng Node làm loại riêng của nó. Liệu nó có liên quan đến thực tế là nếu bạn không bao gồm một nút trường hợp thấp hơn thì khi trình biên dịch đánh giá mã, nó sẽ không thể hiểu được ý nghĩa của "struct node * next"?

+1

Nếu không, nó sẽ là cấu trúc chưa đặt tên. Lưu ý rằng 'Node' không phải là tên vì nó chỉ là một hack typedef để tránh sử dụng' struct node' ở khắp mọi nơi. – Mysticial

+0

Bạn có ý nghĩa gì khi hack? Nó là một phần của ngôn ngữ chính nó để có thể làm Node thay vì nút struct, phải không? –

+0

Đó là một hack thường được sử dụng mà không ai coi đó là một hack nữa. – Mysticial

Trả lời

16

Hãy nhìn vào tuyên bố này:

struct node { 
    int data; 
    struct node *next; 
}; 

typedef struct node Node; 

này có thể được kết hợp thành một tuyên bố đơn (đơn giản hóa một tuyên bố):

typedef struct node { 
    int data; 
    struct node *next; 
} Node; 
+5

Câu trả lời tuyệt vời. –

+2

Bạn cũng có thể sử dụng: 'typedef struct node Node; struct node {int dữ liệu; Nút * tiếp theo; }; '. Typedef đặt tên không hoàn chỉnh; 'struct node' sau đó hoàn tất kiểu không đầy đủ, nhưng có thể sử dụng tên' Node' bên trong. –

1

Ông được xác định một tạm tên cho nút bởi vì anh ta đang sử dụng một kỹ thuật cũng biết để tránh viết struct node trên khai báo của mỗi đối tượng struct.

Nếu ông sẽ chỉ làm:

struct node { 
    int data; 
    struct node *next; 
}; 

bạn sẽ phải sử dụng:

struct node* node; 

để tuyên bố một nút mới. Và để tránh điều đó bạn sẽ phải xác định sau:

typedef struct node Node; 

để có thể khai báo các đối tượng như sau:

Node* node; 

Cuối cùng:

typedef struct node { 
    int data; 
    struct node *next; 
} Node; 

chỉ là lối tắt cho struct node { ... }; ngoài typedef struct node Node;.

0

Đây struct node là một loại như int

và Do đó

struct node { 
    int data; 
    struct node *next; 
}NodeVar; 

có nghĩa là bạn đang tuyên bố một Node biến duy nhất của nút struct.

như int intVar;

typedef là làm cho mã của bạn dễ hiểu.

để khi bạn sử dụng

typedef struct node Node; 

bạn có thể sử dụng tờ khai giống như

Node NodeVar; 
0

xem xét mã này:

#include <stdio.h> 

typedef struct { 
    int data; 
    struct node *next; 
} Node; 

int main() 
{ 
    Node a, b = {10, NULL}; 
    a.next = &b; 

    printf("%d\n", a.next->data); 
} 

này sẽ không biên dịch. Trình biên dịch không có ý tưởng gì là struct node, khác với nó tồn tại. Vì vậy, bạn có thể thay đổi định nghĩa trong cấu trúc thành Node *next;. Typedef không nằm trong phạm vi trước khi nó được khai báo, vì vậy nó sẽ không biên dịch. Câu trả lời đơn giản là làm như ông đã nói, sử dụng thẻ node sau struct và nó hoạt động tốt.

10

Liệu nó có cái gì để làm với thực tế rằng nếu bạn không bao gồm một trường hợp thấp hơn node sau đó khi trình biên dịch được đánh giá mã nó sẽ không thể hiểu những gì có nghĩa là "struct node *next"?

Có.

node trong struct nodethẻ loại cấu trúc. Nếu bạn cung cấp cho các struct một thẻ, bạn có thể tham khảo kiểu đó từ thời điểm này trên thẻ hoàn tất, vì vậy trong

typedef struct node { 
    int data; 
    struct node *next; 
} Node; 

các struct node *next; tuyên bố thành viên next đó là một con trỏ đến kiểu struct được xác định. Tên typedef Node không có sẵn trước khi đạt được kết quả định nghĩa là ;.

Nếu bạn bỏ qua các thẻ, bạn không thể tham khảo các loại được xác định bằng mọi cách trước khi typedef hoàn tất, vì vậy trong

typedef struct { 
    int data; 
    struct node *next; 
} Node; 

dòng struct node *next; tuyên bố một mới, không liên quan, không đầy đủ struct loại với thẻ nodenext trỏ tới.

Đó là hợp lệ, nhưng không về struct node được biết (trừ khi nó được định nghĩa ở một nơi khác), vì vậy bạn không thể sử dụng con trỏ next mà không đúc nó vào một con trỏ tới một kiểu hoàn toàn ở khắp mọi nơi (không hoàn toàn ở khắp mọi nơi, Node foo; foo.next = malloc(12);, vv vẫn sẽ hoạt động).

+0

Tôi hỗ trợ các câu trả lời phức tạp và tốt. –

+0

Giải thích của bạn ở đây có ý nghĩa hơn với tôi nhiều hơn câu trả lời đúng được chọn. – vastlysuperiorman

0

Trường hợp 'nút' thấp hơn là loại cấu trúc ... tức là nút cấu trúc {stuff} là cấu trúc nút chứa nội dung.

Mặt khác, các chữ in hoa "Node" là một kiểu dữ liệu hoàn toàn mới trong đó đề cập đến một 'struct nút'

chung (mặc dù trong C++ Tôi nghĩ rằng bạn có thể), bạn không thể vượt qua xung quanh một " nút "trong một chương trình C ... ví dụ như một đối số cho một hàm. Thay vào đó, bạn sẽ phải chuyển 'nút cấu trúc' làm đối số của mình ...

// this will throw a syntax error because "node" is not a data type, 
// it's a structure type. 

void myFunc(node* arg); 

// while this will not because we're telling the compiler we're 
// passing a struct of node 

void myFunc(struct node* arg); 

// On the other hand, you *can* use the typedef shorthand to declare 
// passing a pointer to a custom data type that has been defined 
// as 'struct node' 

void myFunc(Node* arg);