*(char **)如何理解这个结构?

时间:2012-06-10 03:28:22

标签: c++ c pointers

最近,在我当前项目中读取前代码时,我遇到了以下问题:

在实现Queue时,我的前代写了这样的代码:

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(即''),*(char**)tmp会将其转换为指针形式,但......它怎么会有意义呢?

非常感谢。

4 个答案:

答案 0 :(得分: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);
}

现在假设我们并不真正关心可维护的代码,或者其他方面都是懒惰的。我们可能只是想象任何指针都会做,并将'node'的结构保留在我们的头脑中,然后写:

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);
}

答案 1 :(得分:2)

Queue结构可能是......一个队列。并且它的第一个元素似乎是指向队列的下一个或上一个项目的指针。听起来编码器不能使用他正在创建的类型 - 队列 - 在队列本身内。

例如,解决方案是

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

回到你的问题,

  char *tmp = uq->pHead;

tmp设置为当前的Queue项(保存以供以后使用)

  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
    //... 
  }

答案 2 :(得分:2)

在这个队列中,pHead指向另一个pHead.More恰当地写成:

 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;  

对不起,如果我困惑你。

答案 3 :(得分: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;        
}`        

您可以从此代码中获得所需内容。