我一直坚持修改指针指针。问题是我不明白为什么我的代码有效。我要做的是修改指针指向函数的位置。然后在我的main函数中访问该值。我尝试了很多尝试,这是我开始工作的唯一方法。
#include <iostream>
using namespace std;
void changePP(int **ppint) {
int *n = new int;
*n = 9; //just a value for demonstration purposes
*ppint = n; //THE LINE IN QUESTION
delete n;
}
int main() {
int **ppint = NULL;
int *p = new int;
*p = 4; //another value for demonstrating
ppint = &p;
cout << **ppint << endl;
changePP(ppint);
cout << **ppint << endl;
}
因此,输出为4,然后是单独的9行。但是,我不确定代码中的行*ppint = n
。为什么我必须使用*
来改变ppint指向changePP函数的位置而不是主要的?为什么我不必在函数中使用&
?我似乎无法找到一个我能在互联网上理解的解释,我想知道是否有人可以为我解释这个?
答案 0 :(得分:7)
注意:这些内存地址仅用于说明。
0x0A | 4
0x0B | 'p' -> 0x0A // Pointer to the value 4 in location 0x0A
0x0C | 'ppint' -> NULL // Initially a null pointer
执行ppint = &p;
会产生以下结果,因为此处ppint
是位于0x0C
的指针。
0x0A | 4
0x0B | 'p' -> 0x0A
0x0C | 'ppint' -> 0x0B
对于changePP
函数中的参数,我将其称为ppintCopy
,以减少混淆。它是一个副本(即不同于ppint
的指针),修改它只会修改副本。
0x0D | 'ppintCopy' -> 0x0C // A pointer that points to `ppint`
执行ppintCopy = &n
将修改0x0D
处的指针,该指针不是main
函数指针的位置。 但是,引用ppintCopy
(即*ppintCopy
)会产生0X0C
,这是main
函数的指针,因此*ppintCopy = n;
正在发生变化指针0x0C
指向的地方。
为什么我必须使用*来改变ppint指向changePP函数的位置而不是主要的?
通过上面的插图,我希望更清楚为什么它适用于main
以及为什么必须在changePP
函数中使用不同的语法。
另外,为什么我不必使用&amp;在功能?
在main
函数中,变量ppint
的类型为int**
(即指向指针的指针),而p
的类型为int*
。您无法执行ppint = p;
,因为它们是不同的类型。如果删除一个间接级别,这可能更容易看到。例如:
int* pMyInt = NULL;
int myInt = 3;
我认为这是非常自我解释的,这是行不通的(即,它们是不同的类型)。
pMyInt = myInt;
但是,您可以使用myInt
运算符取&
的地址,这会导致指向int的指针(即int*
),因为此类型与pMyInt
现在可以进行任务。
pMyInt = &myInt;
答案 1 :(得分:5)
ppint; // the variable name
*ppint; // dereference the first layer of pointer
*(*ppint); // dereference the first layer of pointer which points to another pointer that contains a **value**
因此*ppint = n;
表示指向ppint
到另一个内存位置,这是分配给n
的位置,或者可以将其重写为*ppint = &n;
< / p>
在该行之后,您已删除n
,但您没有更改其值,因此值保持不变,除非已访问并修改了某些内容。
在删除它之后仍然保留n
值的原因被认为是未定义的行为。
答案 2 :(得分:3)
指针已经很难处理,你没有必要让它变得更糟。这也有效:
#include <iostream>
using namespace std;
void changePP(int *ppint) {
*ppint = 9;
}
int main() {
int p = 4;
int *ppint = &p;
cout << *ppint << endl; // this could be replaced with /*p*/
changePP(ppint); // note you could have replaced this parameter with /*&p*/
cout << *ppint << endl; // this could be replaced with /*p*/
}
让我试着解释一下你的代码在做什么,但是为了将来,请不要这样做。按照我展示的方式进行操作
#include <iostream>
using namespace std;
void changePP(int **ppint) {
int *n = new int; // you allocate memory for a single integer (again it is uninitialised)
*n = 9; // the value at the above pointer is now changed to 9
*ppint = n; // here you have just dereferenced a pointer to pointer which gives you a pointer, so in essence you are changing the location in memory where this pointer is pointing and it is now pointing to whatever memory address n was
delete n;
}
int main() {
int **ppint = NULL; // Here you have declared a pointer to pointer which is NULL
int *p = new int; // You can do better here with /*new int(4)*/
*p = 4; // this changes the value that p initially held (which could be anything)
ppint = &p; // reference to a pointer always creates a pointer to a pointer and since that is what ppint is, you are safe here
cout << **ppint << endl; // print the value nested within this pointer
changePP(ppint); // now you call the function with a variable of type pointer to pointer. Note you could have passed &p as parameter here and it would have still worked
cout << **ppint << endl;
}
故事的寓意是什么?
将参数v
传递给函数时,
&v
将生成指向v *v
将取消引用v并允许您访问指向v
当v
是函数中的参数时,
&v
会将实际对象v
带入函数的范围。这称为传递参考*v
是一个指向v的指针,这是