** C中的指针和*指针

时间:2013-10-15 09:21:08

标签: c

我正在尝试在链接列表中添加一个简单的程序,并在开始之间添加。

#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()做同样的事情,当我将**更改为*时,更改没有反映出来。为什么会这样?无论如何,如果addatbeg(struct node *,int num),那么指针也指向同一堆。

2 个答案:

答案 0 :(得分:2)

这里的问题是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 *)。同样的事情是在这里进行额外的解除引用。

答案 1 :(得分:1)

您需要**根据需要包含头指针所包含的值,该指针将包含链接列表第一个节点的地址。您正在传递地址的地址,因此您需要一个双指针