c - C中的**指针和*指针

标签 c

<分区>

我正在尝试一个简单的链表程序,在 between 和 beginning 之间添加。

#include<stdio.h>
#include<malloc.h>

struct node{
    int data;
    struct node* link;
};

/* Count the no of items in the list */
int count(struct node* q){
    int c = 0;
    while(q != NULL){
        q = q->link;
        c++;
    }
    return c;
}

/* Add a list at the last */
void append(struct node **q,int num){
    struct node *temp,*r;
    temp = *q;

    /* List is empty */
    if(temp == NULL){
        temp = malloc(sizeof(struct node));
        temp->data = num;
        temp->link = NULL;
        *q = temp;  
    }
    else{
        /* go to the last node */
        while(temp->link != NULL){
            temp = temp->link;
        }

        /* add node at the end */
        r = malloc(sizeof(struct node));
        r->data = num;
        r->link = NULL;
        temp->link = r;
    }
}   

/* add a node after the specific node */
void addafter(struct node *q,int loc,int num){
    struct node *temp,*r;
    int i;

    temp = q;

    /* Skip to the desired portion */
    for(i = 0; i < loc; i++){
        temp = temp->link;
        if(temp == NULL){
            printf("\n Few nodes - less nodes %d elements in list \n",loc);
            return;
        }
    }   

    /* insert new node */
    r = malloc(sizeof(struct node));
    r->data = num;
    r->link = temp->link;
    temp->link = r;
}

/* add a node at the beginning */
void addatbeg(struct node **q, int num){
    struct node *temp;

    /* add a new node */
    temp = malloc(sizeof(struct node));

    temp->data = num;
    temp->link = *q;
    *q = temp;
}

/* Delete a linked list */
void delete(struct node **q,int num){
    struct node *temp,*old;

    temp = *q;
    while(temp != NULL){
        if(temp->data == num){
            /* Node to be deleted is the first node */
            if(temp == *q){
                *q = temp->link;
                free(temp);
                return;
            }
            else{
            /* Delete the Intermdediate nodes */
            old->link = temp->link;
            free(temp);
            return;
            }
        }
        else{
            /* Traverse the linked list */
            old = temp;
            temp = temp->link;
        }
    }
}

/*  Display the data in the list */
void display(struct node *q){
    printf("\n");
    while(q != NULL){
        printf("\n Data : %d \n",q->data);
        q = q->link;
    }
}

int main(){
    struct node *p;
    p = NULL; /* Empty linked list */

    printf("\n No of items in linked list : %d\n",count(p));

    append(&p,100);
    append(&p,200);
    append(&p,300);
    append(&p,400);
    append(&p,500);
    append(&p,600);
    append(&p,700);
    append(&p,800);
    display(p);

    addatbeg(&p,10);
    addatbeg(&p,20);
    addatbeg(&p,30);
    display(p);

    addafter(p,0,1000);
    addafter(p,6,2000);
    addafter(p,9,3000);
    display(p);
    printf("\n No of items in the linked list : %d\n",count(p));

    delete(&p,800);
    delete(&p,500);
    display(p);

    printf("\n No of items in the linked list : %d\n",count(p));

    return 0;
}

我在 addafter() 中遇到问题, 在函数中,我们正在创建指向堆的指针的另一个副本,指针所做的更改将影响在 main 中声明的指针,因为它指向堆的同一地址。 所以我想我会对 addatbeg() 做同样的事情,当我将 ** 更改为 * 时,这些更改没有反射(reflect)出来。为什么会这样?不管怎样,如果 addatbeg(struct node *,int num),那么指针也指向同一个堆。

最佳答案

这里的问题是p在main()中被定义为

struct node *p;

现在,当您将它传递给 addatbeg() 时,您希望更改存储在 p 的地址,因为它将指向已添加到列表开头的另一个节点。但是,当您使用类似

的定义时
addatbeg(struct node *,int num)

p其实是按值传递的。为了修改main中的p,你需要传递它的地址

addatbeg(struct node **,int num)

addafter 中,您不传递 p 的地址,因为您不希望您的头指针发生变化。

您可以将这种情况与更简单的情况进行比较。当你按值传递一个整数时,你使用 foo(int),但是当你想修改原始整数时,你传递它的地址,如 foo(int *)。这里发生了同样的事情,但有一个额外的取消引用级别。

关于c - C中的**指针和*指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19377533/

相关文章:

c - 我该如何用 C 来做到这一点?斐波那契数列

c - 将文件移出文件夹 C

c - 如何使用用户输入的结构填充动态数组的元素?

C Fuctions 中使用的 Heap 还不清楚

c++ - 如何将 gmail 中的 mpz_t 存储在 mongodb 上?

c - 无法理解链表(c)

C 调试宏(具有不同的调试 "sources")

c - 为什么这个 MPI 程序停滞

objective-c - 用于维护磁盘缓存的库

C typedef结构的不确定性