欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据结构(二)——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;
}

运行结果:
数据结构(二)——C++中的*&
可以看到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;
}

运行结果:
数据结构(二)——C++中的*&
运行foo2():

int main(){ 

   int a = 1;
   int *b = &a;
   
   foo2(b);
   
   return 0;
}

运行结果:
数据结构(二)——C++中的*&

可以观察到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;
}

运行结果:
数据结构(二)——C++中的*&

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;
}

运行结果:
数据结构(二)——C++中的*&
第二段代码成功地将b的值改为了0,第一段代码没有改动b的值。因为 *&b传入的是b的地址, b传入的是b的值,并在函数中临时分配了另一地址0x66ff00用于存储0x66ff24.所以在传入b时不会改变函数外b的值。

上表格!
数据结构(二)——C++中的*&

这也是为什么只有*&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中元素。