c - 更改函数中传递的指针
问题描述
关于双重间接(指向指针的指针)并将它们传递给函数
我无法在函数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( ..)
解决方案
在函数中,对指针变量或指针参数的更改对函数外部没有影响。但是,如果指针指向函数外部的对象,则可以通过取消引用指针来修改该对象。
例如,在 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
对象已通过取消引用指针并分配给它所指向的成员而被修改。current
next
Person
推荐阅读
- wpf - WPF按钮未触发单击事件
- c# - LINQ 当前记录和两边的 x 条记录
- django - NameError at "" name 'pk__in' 未定义
- javascript - xPath里面的xPath?
- r - 升级到 R 3.6.2 后无法在我的 Ubuntu 14.04 上安装任何 R 包
- php - PHP没有从自定义字段中提取元数据
- python - Pandas 在列的固定间隔上取平均值
- facebook - 如何使用基本显示 API 获取多个不同的 Instagram 用户最近的帖子
- laravel - Laravel 5.8 - 如何在视图中从控制器转储参数
- c# - 需要一些帮助,将文本框的转换放在哪里