我不明白为什么将pointer
地址作为parameter
传递给function
的修改不会在此函数之外保留(ptr
的地址不存在调用此函数后不要更改:
void advance(int *ptr) {
ptr = ptr + 1
}
当我可以在同一个函数中修改value
:ptr
指向的*ptr = *ptr + 1
时。
PS:我知道我可以使用pointer to a pointer
:**ptr
实现我的目标。
答案 0 :(得分:2)
这种行为是因为C中函数的参数总是通过值传递。你在这里传递的价值是一个地址。当您修改ptr
时,您正在修改来电者值的副本。
要修改调用者的值,您需要额外的间接级别:
void advance(int **ptr) {
*ptr = *ptr + 1;
}
答案 1 :(得分:1)
因为C 不通过引用调用,所以它总是按值调用,即使引用/指针作为参数。
它与其他语言不同,它可以区分参数类型。
答案 2 :(得分:1)
当你定义函数void advance(int * ptr)时,它意味着将创建堆栈中的指针,该指针指向与原始指针相同的地址。要查看证明,请尝试打印orig指针(& orig)的地址和参数指针(& param)的地址,以及“指向”地址(orig,param)。指针地址会有所不同,但指向的地址将是相同的。
所以我们有两个指向同一区域的指针,如果修改参数,它将指向新区域,但是orig值不会改变,它指向与之前相同的区域。
这就是你需要一个指向指针的原因。如果你使用指向指针的指针(int ** ppointer =& orig),你将有一个指针直接指向orig存储“指向”地址的区域(当前的orig点)。通过更改* ppointer的值,您也可以直接更改orig的值。
答案 3 :(得分:0)
你实际上回答了你自己的问题;)
作为参数传递给函数的指针地址的修改不会在此函数之外持久存在
在功能内部,您正在管理参数的副本。 您可以修改指向的值,因为您明确要求在特定地址进行更改。
答案 4 :(得分:0)
void advance(int *ptr)
函数调用将在堆栈中创建一个名为ptr的新变量(在高级函数的堆栈中),这是一个指向整数的指针,递增它,只有当你进入advace函数时该函数才有效,退出高级功能后,变量将丢失。高级功能的堆栈不再存在
答案 5 :(得分:0)
****** /---\ * 20 * ----> | 2 | ****** \---/ i 20-24
此处i
是指向存储位置20
的指针,其具有值2
,即当20 + sizeof(int) - 1
中的二进制数据被解释为十进制数时。现在,当您将i
传递给具有参数advance
的{{1}}时,实际发生的是
****** /---\ ****** * 20 * ----> | 2 | <---- * 20 * ****** \---/ ****** i 20-24 ptr
ptr
即ptr = i;
的值设置为i
的值,这里的确是地址,因为ptr
和i
是指针。
当您递增ptr
时,它只会使指针指向不同的地址而不会更改ptr
的任何内容,因为i
是副本,而不是ptr
本身。但是,如果您使用运算符i
更改ptr
处的值,即*
;然后上面的*ptr = 10
会更改为2
,从而也会更改10
,这也会指向20.再次注意*i
的地址或值未受影响,仅它所指向的位置经历了变化。如果有10个指针指向地址i
,即使这样,它们也都没有被改变,但它们的所有指向值都会改变。
答案 6 :(得分:0)
见功能:
void demonstrate(int num) {
num = num + 1; // type of num is int
} // destroys "num", because num's scope is only "demonstrate" function
在你的功能中:
void advance(int *ptr) {
ptr = ptr + 1; // type of ptr is int* and ptr is incremented
} // destroys "ptr" for the similar reason
但是你想要一个修改地址的功能( IN 指针)。所以完整的解决方案应该是:
#include <stdio.h>
void advance(int **ptr) { //ptr is a pointer to a pointer
// so *ptr is the pointer that is pointed by ptr
*ptr = *ptr + 1; // incrementing the address IN the pointer pointed by ptr
} // destroys "ptr" for the reason above
int main() {
int x = 5;
// initially assign "ptrToChange"
int *ptrToChange = &x;
// "ptrToChange" now points to x
// passing address OF "ptrToChange" to "advance" function
advance(&ptrToChange);
// now "ptrToChange" does NOT point to x
return 0;
}