2017-07-05 7 views
1

私はプログラミングと読書のためのプライマーですプライマー:第5版。何が私を混乱させる理由は、リストへのポインタとしてplistもノードを指すことができますか?なぜListへのポインタもNodeを指すことができますか?

申し訳ありませんが、私はコードブロックに関数ListItemCountを貼り付けませんでした。この関数のNode * pnode = *plist;は、plistがポンターポイントとしてNodeに変換されたことを意味しますか?その場合、plist->headpnode(Nodeへのポインタ)に代入するのではなく、プログラムがノードへのポインタに変換する必要があるのはなぜですか?

typedef struct film { 
    char title[TSIZE]; 
    int rating; 
} Item; 

typedef struct node{ 
    Item item; 
    // typical usage 
    struct node * next; 
} Node; 


/* 
* Note: to manage a linked list, we need a pointer to its beginning, 
* and we've used typedef to make List the name for a pointer of this 
* type. 
*/ 
typedef struct list{ 
    // should point to linked list Node 
    Node * head; 

    int size; 
} List; 

// TODO why `plist` as a pointer to List can also point to Node? 
/* returns number of nodes */ 
unsigned int ListItemCount(const List * plist) 
{ 
    unsigned int count = 0; 
    Node * pnode = *plist; /* set to start of list */ 
    while (pnode != NULL) 
    { 
     ++count; 
     pnode = pnode->next; /* set to next node */ 
    } 
    return count; 
} 
+1

ポインタが何を指すことができます。上記のポインタから "意味のある"データを読み込もうとすると、間違ったことが起こります。 'List'ポインタを' Node'ポインタにキャストしようとすると、間違いなくいくつかのコンパイラの警告が出ます。 –

+0

それはできません。なぜそう思うの?あなたを混乱させるものを詳しく教えてもらえますか? –

+5

コードスニペットで 'plist'はまったく使用されていません。 – VTT

答えて

0

これはうまくいきません。

どうすればよいですか?

Node * pnode = *plist; 

これは最初のノードを取得するためのものです。実際には、リストタイプを最初のノードとして割り当てようとします。それを動作させるには、ヘッドノードをそれから取り除く必要があります。

Node * pnode = (*plist).head; 

これは今実際にはもっと簡潔にこれを書き込むにはNode* を返します。

Node * pnode = plist->head; 
1

コンパイラは、そのコードについて警告を鳴らす必要があります。

しかし

List構造のメモリレイアウトは

 
+------+------+ 
| head | size | 
+------+------+ 

ようなものです...それがどのように機能するかを見てみましょう(上の図は、可能なパディングを無視します。)

変数plistは、その構造体の先頭を指します。

 
+------+------+ 
| head | size | 
+------+------+ 
^ 
| 
plist 

ご覧のとおり、headが格納されている場所を指しています。だからplistを逆参照することにより、headのメンバーを得ることができます。

しかし、それはであり、悪いコードであり、そのようなコードを書くべきではありません。コードを読みやすく、理解し、維持するのが難しくなります。明示して使用してください。代わりに代わりに

Node * pnode = plist->head; /* set to start of list */ 

を使用してください。

関連する問題