【问题标题】:How to use correct pointer in this linked list如何在此链表中使用正确的指针
【发布时间】:2021-02-19 11:56:05
【问题描述】:

这是我从 codesdope.com 获得的代码,我稍作修改以了解带有链表的队列 ADT 的工作原理。

但是,我在此代码上使用指针时卡住了。 我只是试图打印出队列中的所有元素,试图改变参数。 而且我无法从队列中转到下一个节点,我是否尝试了这段代码不可能的事情? 因为它是这样设计的还是这里有任何解决方案?

我需要你的帮助或提示如何使用正确的指针跟随指针。

'''

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define FULL 10


typedef struct node{
    int data;
    struct node *next;
} NodeT;


typedef struct QueueRep{
    int length;
    NodeT *head;
    NodeT *tail;
} QueueRep;

typedef struct QueueRep *queue;


void initialize(queue q){
    q->length = 0;
    q->head = NULL;
    q->tail = NULL;
}


int isempty(queue q) {
    return(q->tail == NULL);
}

void enqueue(QueueRep *q, int value) {
    if(q->length < FULL) {
        NodeT *tmp;
        tmp = malloc(sizeof(NodeT));
        tmp->data = value;
        tmp->next = NULL;
        if(!isempty(q)) {
            q->tail->next = tmp;
            q->tail = tmp;
        } else {
            q->head = q->tail = tmp;
        } 
        q->length++;
    } else {
        printf("List is full\n");
    }
}

int dequeue(QueueRep *q) {
    NodeT *tmp;
    int n = q->head->data;
    tmp = q->head;
    q->head = q->head->next;
    q->length--;
    free(tmp);
    return(n);
}

/* original display function
void display(NodeT *head)
{
    if(head == NULL)
    {
        printf("NULL\n");
    }
    else
    {
        printf("%d\n", head -> data);
        display(head->next);
    }
}
*/

/* I would like to print like this !!!! */
void display(queue q) {
    NodeT *p = q->head;
    if(p->data == NULL) {
        printf("NULL\n");
    } else {
        printf("%d ", p->data);
        display(q->head); //wrong pointer? how can your fix here?
        
    }
    
}



int main() {
    QueueRep *q;
    q = malloc(sizeof(QueueRep));
    initialize(q);
    enqueue(q,10);
    enqueue(q,20);
    enqueue(q,30);
    printf("Queue before dequeue\n");
    //display(q->head); 
    display(q); //this is What I am trying to use
    dequeue(q);
    printf("\nQueue after dequeue\n");
    //display(q->head);
    display(q); //this is What I am trying to use
    return 0;
}

'''

【问题讨论】:

  • 这只是一个糟糕的代码。有什么问题?
  • 数据成员不是指针。所以这个 if 语句 if(p->data == NULL) { 没有意义。
  • 在这个递归调用中显示(q->head);参数的类型与函数参数的类型不同。

标签: c pointers recursion queue function-definition


【解决方案1】:

这个函数定义

/* I would like to print like this !!!! */
void display(queue q) {
    NodeT *p = q->head;
    if(p->data == NULL) {
        printf("NULL\n");
    } else {
        printf("%d ", p->data);
        display(q->head); //wrong pointer? how can your fix here?
    }
}

错了,不能编译。

例如结构node的数据成员data不是指针。所以这个 if 语句

    if(p->data == NULL) {

无效,因为将int (p-&gt;data) 类型的对象与空指针NULL 进行了比较。

在此声明中

display(q->head); //wrong pointer? how can your fix here?

函数使用struct node 类型的参数调用,而相应的函数参数的类型为queue。所以编译器会再次为这个语句发出错误。

您可以将函数拆分为两个函数。例如

void display_list( const NodeT *head )
{
    if ( !head )
    {
        puts( "NULL" );
    }
    else
    {
        printf( "%d ", head->data );
        display_list( head->next );
    }
} 

void display( const QueueRep *q ) 
{
    display_list( q->head );
}

函数dequeue

int dequeue(QueueRep *q) {
    NodeT *tmp;
    int n = q->head->data;
    tmp = q->head;
    q->head = q->head->next;
    q->length--;
    free(tmp);
    return(n);
}

可以调用未定义的行为。首先它不检查队列是否为空/。其次,当队列中的单个节点被删除时,它不会将指针tail 设置为NULL

函数可以定义为例如以下方式

int dequeue( QueueRep *q, int *data ) 
{
    int success = q->head != NULL;

    if ( success )
    {
        NodeT *tmp = q->head;
        *data = tmp->data;

        q->head = q->head->next;
        if ( !q->head ) q->tail = NULL;
        --q->length;
 
        free( tmp );
    }

    return success;
}

请注意,在 main 中动态声明 QueueRep 类型的对象没有多大意义。你可以写

QueueRep q;
initialize( &q );

还有这个typedef

typedef struct QueueRep *queue;

只会让代码的读者感到困惑。在程序的某些地方您使用QueueRep * 类型,而在其他地方您使用queue 类型。

【讨论】:

  • 非常感谢弗拉德! огромное спасибо
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 2012-02-20
  • 2014-03-08
  • 2019-11-10
  • 1970-01-01
相关资源
最近更新 更多