首页 > 解决方案 > 更改函数中传递的指针

问题描述

关于双重间接(指向指针的指针)并将它们传递给函数

我无法在函数void test(int **nmbr, int *n);中更改指针。

int n = 5;
int n2 = 555;   

int *nPtr = &n;
int *n2Ptr = &n2;

printf("the number = %d\n", *nPtr);

test(&nPtr, n2Ptr);

printf("the number is now = %d\n", *nPtr);

测试

void test(int **nPptr, int *n2Ptr) {

 int *p = *nPptr;

 p = n2Ptr;

}

因为指针 p 指向 *nPtr 的副本,对吧?

但是这段代码呢(这次指针指向链表中的给定结构

截取的代码来自网站https://www.learn-c.org/en/Linked_lists

 int remove_by_index(Person **head, int n) {
int i = 0;
int retval = -1;
Person *current = *head;
Person *temp_node = NULL;

if (n == 0) {
    return pop_first(head);
}

for (i = 0; i < n-1; i++) {
    if (current->next == NULL) {
        return -1;
    }
    current = current->next;
}

temp_node = current->next;
retval = temp_node->nmbr;
current->next = temp_node->next;
free(temp_node);

return retval;

}

它通过给定的索引号删除列表中的给定节点

这里可以看到 *current 是函数中的本地副本,在列表中遍历,最后合并两个节点,没有问题

那么为什么在此处更改指针而不是在函数 test(int **nPptr, int *n2Ptr) 中更改指针起作用?

要清楚

在功能测试中:

 int *p = *nPptr;

p 是本地副本,从 *nPtr 复制指针

在函数remove_by_index

Person *current = *head;

current 是本地副本,并从 *head 复制指针。该列表超出了函数 remove_by_index(..) 的范围,所以我不明白为什么它可以在函数中通过本地指针 *current 进行操作,同时在函数 test( ..)

标签: cpointersstruct

解决方案


在函数中,对指针变量或指针参数的更改对函数外部没有影响。但是,如果指针指向函数外部的对象,则可以通过取消引用指针来修改该对象。

例如,在 OP 的test函数中:

void test(int **nPptr, int *n2Ptr) {
    int *p = *nPptr;

    p = n2Ptr;
}

p被初始化,然后通过赋值改变它的值。这对函数之外的任何对象都没有影响。如果函数更改如下:

void test(int **nPptr, int *n2Ptr) {
    int *p = *nPptr;

    p = n2Ptr;

    *nPptr = p;
    *p = 42;
}

然后函数外部的两个对象将被修改(anint *和 an int)。

在 OP 的remove_by_index函数中,current变量在链表中的变化没有外部影响,但是行:

current->next = temp_node->next;

相当于:

(*current).next = (*temp_node).next;

指向链表上的外部Person对象已通过取消引用指针并分配给它所指向的成员而被修改。currentnextPerson


推荐阅读