2

最近、現在のプロジェクトで以前のコードを読んでいるときに、次の問題が発生しました。

キューを実装している間、私の前者は次のようなコードを書きました:

while(uq->pHead)
{
    char *tmp = uq->pHead;
    uq->pHead = *(char **)tmp;
    //...
}

uq->pHead には次のような定義があります。

typedef struct {
        char* pHead;
        //...
} Queue;

ええと、「 」という使い方についてかなり混乱していますuq->pHead = *(char**)tmp。誰か詳しく説明してもらえませんか?

*(uq->pHead) = 32(ie ' ') と仮定すると、*(char**)tmpこれはポインタ形式に変換されますが...どうして意味があるのでしょうか?

どうもありがとう。

4

4 に答える 4

6

Queue をリンクされたリストとして実装しているとしましょう。次のような場合があります。

struct data_type;

struct node
{
    node *next;
    data_type item;
};

struct linked_list
{
    node *pHead;
    // ...
};

リンクされたリストを空にするには、次のように記述します。

linked_list *uq=...;
while (uq->pHead)
{
    // unlink the first node from the list
    node *tmp = uq->pHead;
    uq->pHead = tmp->next; 

    // do something with that node
    // ...

    // deallocate the node
    free(tmp);
}

ここで、保守可能なコードをあまり気にしないか、怠惰であるとします。代わりに、任意のポインターが機能することを理解し、「ノード」の構造を頭に入れておき、次のように記述します。

linked_list *uq=...;
while (uq->pHead)
{
    // unlink the first node
    char *tmp = uq -> pHead;     // tmp points to the first 'node'
    uq -> pHead = *(char**)tmp;  // The first thing in a 'node' is a pointer to
                                 // the next node.

    // do something with 'tmp', the now unlinked node
    data_type *item=(data_type*) ( ((char**)tmp) + 1 ); // after the 'next' pointer
                                                        // is the real data.
    // ...

    // free up the node
    free(tmp);
}
于 2012-06-10T03:46:38.177 に答える
2

このキューでは、pHeadは別のpHeadへのポインタです。より適切には、次のように記述できます。

 void *pHead;   

また、tmpは次のように書くことができます。

void *tmp;  
tmp = uq->pHead;  

現在のpHeadポインタをtmp変数に保存します。これで、tmpが別のポインターを指していると見なされるよう
に、tmpがキャストされます。はtmpの値であり、ポインタとしても表示されます。 (void **)
*(void **) tmp;

uq->pHead = *(void **) tmp;  

したがって、これによりpHeadが次の要素に増分されます。
このステートメントは、次のように書くこともできます。

uq->pHead = uq->pHead->pHead;  

混乱してすみません。

于 2012-06-10T04:35:22.357 に答える
2

構造体はQueueおそらく...キューです。そして、その最初の要素は、キューの次または前のアイテムへのポインターであるようです。コーダーは、自分が作成しているタイプである Queue を Queue 自体の中で使用しなければならないことに慣れていないようです。

たとえば、解決策は

  typedef struct Queue {
    struct Queue *pHead;
    //...
  } Queue;

質問に戻りますが、

  char *tmp = uq->pHead;

現在のキュー項目に設定tmp(後で使用するために保存)

  uq->pHead = *(char **)tmp;

uq->pHeadポインター値を現在のアイテムの pHead に設定します。char *コーダーは pHead を (の代わりに)適切に宣言しなかったためstruct Queue *、構造ポインター ( uq->pHead== tmp) をキャストchar ***(char **)てから、構造の最初のポインター、つまり を取得しますpHead

上記の宣言を使用すると、コードは

  while(uq->pHead)
  {
    Queue *tmp = uq->pHead;
    uq->pHead = tmp->pHead; // or uq->pHead = uq->pHead->pHead
    //... 
  }
于 2012-06-10T03:58:23.147 に答える
0

Assume your Queue struct has a object named qa, the address of qa's first data is the same as qa's. In C++, you have many ways to invoke data such as,".","->" . But they are all really use offset just like

`#include<cstdio>        
using namespace std;        
class A        
{        
public:        
    int a;        
    int b;        
};        
int main()        
{        
    A a;        
    printf("%p\n",&a);        
    printf("%p\n",& A::a);        
    printf("%p\n",& A::b);        
    printf("%p\n",&(a.a));        
    printf("%p\n",&(a.b));        
    return 0;        
}`        

You can get what you want from this code.

于 2012-06-10T06:19:41.827 に答える