问题描述
一个数组现在由单个指针指向。双指针指向单个指针。我正在尝试使用此双指针获取数组的值。到目前为止,我只通过 double指针获取了数组的第一个索引值。
我知道,如果我取消引用(*ptr2
)双指针,那么它将给出第一个指针指向的地址(ptr1
),这意味着数组的第一个索引地址(&array[0]
)。
#include <iostream>
using namespace std;
int main(){
int array[5]{15,25,35,45,55};
int* ptr1;
int** ptr2;
ptr1 = &array[0];
ptr2 = &ptr1;
在下面的for循环中,我尝试使用指针array
打印ptr1
的值。
for(int i =0; i<5; i++){
cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n";
}
cout<<"\n";
在下面的for循环中,我尝试检查*ptr2
是否一直在给我指向ptr1
所指向的地址。但是我发现它只对第一个索引有效/相同,然后它(*ptr2
)给了我一个不同的地址
for(int j=0; j<5; j++){
cout<<"adress of array: "<<&array[j]<<",ptr1: "<<(ptr1+j)<<",val of ptr2: "<<*(ptr2+j)<<endl;
}
cout<<"\n";
return 0;
}
虽然我尝试使用**ptr2+i
通过for循环从ptr2取值,但它仅持续2次。第一次正确的值很明显,因为我看到array[0]
和*(ptr2+0)
的地址是相同的。第二次垃圾值,然后是分段故障(核心已转储)。
我想到一个猜测,ptr1
和ptr2
都是int
类型,但是一个指向变量,另一个指向指针。因此也许从一开始就出现了内存分配概念。
解决方法
ptr2
指向ptr1
。 (ptr2+j)
(当j
不是0
时,是您尚未分配的地址,因此对其进行取消引用(*(ptr2+j)
)使您的程序具有undefined behavior并得到一个分段错误是一种可能的结果。
您应该先取消引用它,然后再索引:(*ptr2)[j]
或*((*ptr2)+j)
。
您的推理很接近,但是您没有很好地运用它。
我知道,如果我取消引用(
*ptr2
)双指针,那么它将给出指向第一个指针的地址(ptr1
)
换句话说,*ptr2
是ptr1
的同义词。因此,在您看到ptr1
的任何地方(分配了ptr2 = &ptr1
之后)都可以替换为*ptr2
。更好的是,用(*ptr2)
代替,以避免比取消引用优先级更高的操作员的干扰。让我们举个例子:
for(int i =0; i<5; i++){ cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n"; } cout<<"\n";
现在执行简单的查找和替换。将ptr1
替换为(*ptr2)
。不要试图调整任何东西。一旦您决定执行此操作,该过程就变得毫无意义。
for(int i =0; i<5; i++){
cout<<"the value: "<<*((*ptr2)+i)<<" lives at "<<(*ptr2)+i<<" address\n";
}
cout<<"\n";
这几乎是您在循环中尝试的方法,除了您使用*(ptr2+j)
而非(*ptr2)+i
。我们可以忽略从i
到j
的更改,但是这些括号很重要。您更改了操作顺序,这类似于使用3(1+4)
而不是(3×1)+4
。不足为奇的是,15
在需要7
的地方不起作用,同样地,在取消引用之前添加j
在首先需要取消引用的地方也不起作用。
注意:由于取消引用的优先级高于加法,因此可以从此特定示例中删除*ptr2
周围的括号。也就是说,*ptr2+i
和*(*ptr2+i)
也可以使用。
注意:此问题可以证明为什么通常避免指针对指针是明智的。