簡體   English   中英

指向結構內其他結構的指針

[英]Pointers to other structures within a structure

我的講師提出了以下一段代碼,但沒有充分解釋它代表什么。

typedef struct _s {
    int         value;
    struct _s   *next;
}  STACKITEM;

STACKITEM    *stack = NULL;
  1. 我理解指針和結構是什么。 但是,我不知道在結構中有一個指向結構的指針意味着什么。 請澄清並詳細說明這一概念。

  2. 我不明白為什么結構被聲明為typedef。 由於以下原因,這似乎是多余的:

典型結構如下。

struct struct_format_name { 
members;
} individual_struct_object_name;

因此,我們已經聲明一個對象是一個結構,並且給定了一個結構名稱為_s的格式。 那么使用typedef有什么意義呢? 除了typedef關鍵字之外,它與用於聲明任何結構的格式相同。

  1. 我想澄清指向結構化格式的結構的指針(如上所述)與指向特定結構的結構的指針之間的區別。

我懷疑指向結構化格式的結構的指針,如上所述,可以指向該格式的任何結構? 但是,指向具體結構的結構的指針只能指向該特定結構,而不是相同格式的其他結構?

這稱為鏈表。 next指針是允許您通過讓每個元素指向下一個元素來瀏覽列表,並使最后一個元素具有next指向NULL ,因此您知道自己已經結束了。 請參閱https://en.wikipedia.org/wiki/Linked_list您實際上並沒有存儲結構,而是存儲指向下一個元素的指針,將其視為一個數組,但是在哪里而不是對齊的元素,它們中的每一個都使用其地址指向下一個元素。

至於next指針,使用struct關鍵字聲明它的原因是STACKITEM類型尚不存在(它是在結構定義之后定義的)。

典型結構聲明如下。

只有你永遠不想再創造一個。 您正在質疑的語法是聲明結構的典型方法。

typedef允許您通過struct_format_name的較短名稱而不是struct struct_format_name來引用它。

我理解指針和結構是什么。 但是,我不明白在結構中有一個指向結構的指針意味着什么。 請澄清並詳細說明這一概念。

這是稱為單鏈表的數據結構的常見C實現,其中列表中的每個元素明確指向以下元素。 在這種情況下,每個實例struct _s指向的另一個實例struct _s ,就像這樣:

+---+---+         +---+---+        +---+---+
|   |   | ----->  |   |   | -----> |   |   |
+---+---+         +---+---+        +---+---+
                                     ^   ^
                                     |   |
                                     |   +---- next
                                     +-------- value

您可以使用鏈接列表結構實現堆棧 ,這是您的教師正在執行的操作。 “推”操作將動態創建一個新的STACKITEM ,將整數值保存到它,並使新的STACKITEM成為列表的頭部(也就是堆棧的頂部)。 stack指針始終指向列表中的第一個元素(如果列表為空,則為NULL )。

stack: |||

push( &stack, 1 );

       +---+---+
stack: | 1 |   |---|||
       +---+---+

重復調用push會在列表的頭部添加一個新元素:

push( &stack, 2 );

       +---+---+    +---+---+
stack: | 2 |   |--->| 1 |   |---|||
       +---+---+    +---+---+

push( &stack, 3 );

       +---+---+    +---+---+    +---+---+
stack: | 3 |   |--->| 2 |   |--->| 1 |   |---|||
       +---+---+    +---+---+    +---+---+

代碼看起來像

void push( STACKITEM **stack, int value )
{
  STACKITEM *newItem = malloc( sizeof *newItem );
  if ( newItem )
  {
    newItem->value = value;
    newItem->next  = *stack;    // newItem now points to former top of stack
    *stack         = newItem;   // newItem is now the top of the stack
  }
}

“pop”操作只是反向運行 - 它通過將stack指針設置為指向下一個元素並釋放該元素的內存來刪除列表的第一個元素:

void pop( STACKITEM **stack )
{
  STACKITEM *top = *stack;
  if ( top )
  {
    *stack = top->next;
    free( top );
  }
}

pop( &stack );

       +---+---+    +---+---+
stack: | 2 |   |--->| 1 |   |---|||
       +---+---+    +---+---+

pop( &stack );

       +---+---+
stack: | 1 |   |---|||
       +---+---+

pop( &stack );

stack: |||

我不明白為什么結構被聲明為typedef。 由於以下原因,這似乎是多余的:

typedef兩個基本用途:

  1. 簡化復雜類型名稱
  2. 摘要遠離實現細節

在這種情況下,你的教練的目標是2 -抽象掉的struct棧項目類型的-ness。 不幸的是,如果您作為該類型的用戶必須了解實現細節,那么這不是很有用的。

注意:您的教師不應在標簽名稱中使用前導下划線; 具有前導下划線的標識符保留供實現使用。

結構中的指針與結構外部的指針沒有區別,指向結構類型的指針可以指向該類型的任何對象。

無法定義只能指向特定對象的類型。

您的代碼和講師的代碼沒有完成同樣的事情,所以沒有冗余。
你要定義一個類型和一個對象; 他們為該類型定義了一個類型和一個不同的名稱。
(聽起來有點像你把對象混淆了。)

它們的typedef並不是絕對必要的,但它是一種非常常見的方法,可以避免在使用結構類型時鍵入struct

而你的變化是非常典型的。
類型通常是全局定義的,而變量盡可能在本地聲明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM