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

假设我们将您的队列实现为链表。我们可能有:

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

Queue结构很可能是......一个队列。它的第一个元素似乎是指向队列的下一个或上一个项目的指针。听起来编码员对不得不使用他正在创建的类型 - 队列 - 在队列本身内部感到不舒服。

例如,一个解决方案是

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

回到你的问题,

  char *tmp = uq->pHead;

设置tmp为当前队列项(保存以备后用)

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

uq->pHead指针值设置为当前项目的 pHead。由于编码器没有正确声明 pHead (char *而不是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 回答
2

在这个队列中,pHead 是指向另一个 pHead 的指针。更恰当地说,它可以写成:

 void *pHead;   

tmp 也可以写成:

void *tmp;  
tmp = uq->pHead;  

将当前 pHead 指针保存到 tmp 变量。
现在, tmp 被强制转换为(void **)tmp 被视为指向另一个指针。
*(void **) tmp;是 tmp 处的值,也被视为指针。

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

因此,这会将 pHead 增加到下一个元素。
这个语句也可以写成:

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

对不起,如果我让你感到困惑。

于 2012-06-10T04:35:22.357 回答
0

假设你的 Queue 结构有一个名为 qa 的对象,qa 的第一个数据的地址与 qa 的相同。在 C++ 中,您可以通过多种方式调用数据,例如,".","->" 。但他们都真的像使用偏移量一样

`#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;        
}`        

你可以从这段代码中得到你想要的。

于 2012-06-10T06:19:41.827 回答