数据结构(二)——C++中的*&
程序员文章站
2024-03-06 22:04:26
...
关于C++中*和&的用法及意义这里不再赘述,在各大网站和论坛中有详细且明确的解释。
本文关注 *&,即 *与&同时使用的情况,以及为什么 *&可以实现改变指针。
首先看一段代码:
int main(){
int a = 1;
int *b = &a;
cout << "a value: " << a << endl;
cout << "&a value: " << &a << endl;
cout << "b value: " << b << endl;
cout << "b value: " << &b << endl;
return 0;
}
运行结果:
可以看到a的值为1,取地址符&取到a的地址为0x66ff24,并把地址的值赋给了b,b的值为0x66ff24.
再次利用取地址符&,取到b的地址为0x66ff20,即为地址的地址。
随后我们建立两个函数,传入参数分别为 *p和 *&p。
void foo1(int *p){
cout << "p value: " << p << endl;
cout << "&p value: " << &p << endl;
cout << "*p value: " << *p << endl;
}
void foo2(int *&p){
cout << "p value: " << p << endl;
cout << "&p value: " << &p << endl;
cout << "*p value: " << *p << endl;
}
运行foo1():
int main(){
int a = 1;
int *b = &a;
foo1(b);
return 0;
}
运行结果:
运行foo2():
int main(){
int a = 1;
int *b = &a;
foo2(b);
return 0;
}
运行结果:
可以观察到p的地址并不相同,传入 *&p的函数中,p的地址与函数外相同,传入 *p的函数中,p的地址与函数外不同,该地址从未出现过。
运行以下代码:
void foo3(int *p){
p = NULL;
}
int main(){
int a = 1;
int *b = &a;
cout << "a value: " << a << endl;
cout << "b value: " << b << endl;
foo3(b);
cout << "a value: " << a << endl;
cout << "b value: " << b << endl;
return 0;
}
运行结果:
void foo4(int *&p){
p = NULL;
}
int main(){
int a = 1;
int *b = &a;
cout << "a value: " << a << endl;
cout << "b value: " << b << endl;
foo4(b);
cout << "a value: " << a << endl;
cout << "b value: " << b << endl;
return 0;
}
运行结果:
第二段代码成功地将b的值改为了0,第一段代码没有改动b的值。因为 *&b传入的是b的地址, b传入的是b的值,并在函数中临时分配了另一地址0x66ff00用于存储0x66ff24.所以在传入b时不会改变函数外b的值。
上表格!
这也是为什么只有*&b可以改变指针的值,在上面我们成功把b的值修改为了null。
最后再看一段代码,一个*&的重要应用——变长一维数组。
该代码的目标是确立一个具有新长度的数组,把数组a的元素复制到这个新数组,最后改变数组的值,是它可以引用新数组。
template<class T>
voide changeLength1D(T *&a, int oldLength, int newLength){
if(newLength < 0)
throw illegalParameterValue("new length must be >= 0");
T *temp = new T[newLength];
int number = min(oldLength, newLength);
copy(a, a + number, temp);
deleta []a;
a = temp;
}
传入 *&a,赋予a一个新的数组地址,实现函数外数组a长度变化。假设原数组a的地址为0x1,函数中temp的地址为0x9.经过该函数,原数组的地址改为0x9。
之后调用数组a,首先找到存储数组地址的地址,调出其数据0x9,再依据线性表调用a中元素。