引用
int a = 10; int &b = a; cout << b<< endl;
运行结果,b = 10;
可以把 &b 理解为对 a 取的别名
我们看一下 a 和 b 的地址
0x7ffdcab9f58c 0x7ffdcab9f58c
可以看出来 a 和 b 是公用一块地址的,或者可以理解为 b指向了a的地址
我们试一下修改b的值
int a = 10; int &b = a; b = 20 cout << b<< endl;
cout << a<< endl;
输出结果 20 20 说明引用可以修改所引的变量的值,这点又十分接近指针的效果了。
我们看一个以前在c语言中用到的函数
int sum(int *a,int *b) { return *a + *b; }
使用的时候用 &
int main() { int a = 10; int b = 10; cout<<sum(&a,&b)<<endl; }
我们也可以用&去声明参数
int sum(int &a,int &b) { return a + b; } int main() { int a = 10; int b = 10; cout<<sum(a,b)<<endl; }
再看一个引用作为参数传递的例子
void bar(string &s)
{
cout << s <<endl;
}
当我要调用bar 这个函数时
bar("adf");
这样会报错
正确的传参应该是
void bar(const string &s)
{
cout << s <<endl;
}
使用引用参数时 尽量定义为const
当引用作为返回值:
看这样一段代码
int f()
{
int a = 10;
return a;
}
int &f1() { int a = 10; return a; } int &f2() { static int a = 10; return a; } int main() { cout << f1() <<endl; cout << f2() <<endl; }
运行一下,发现 f1() 是错误的,无法运行,f2()可以正常的返回 a 的值。
说明 当引用作为返回值时,不能返回局部变量,也就是不能超过该函数的作用域。
第一个函数 int f() 返回值为变量的值,返回的是 10 这个整形数字
第三个函数 int &f2() 返回值是变量本身,返回的是 a 这个整形变量 所以引用作为返回值时可以当左值
也就是可以这样使用
f2() = 100;
那么 这个静态变量 a 的值就变成了100
指针和引用的比较
第一个区别在于引用总是指向某个对象:定义引用时没有初始化
是错误的。第二个重要区别则是赋值行为的差异:给引用赋值修改的是该引用所
关联的对象的值,而并不是使引用与另一个对象关联。引用一经初始化,就始终
指向同一个特定对象(这就是为什么引用必须在定义时初始化的原因)。
接下来看一下指针的指针 和 指针的引用
int main(int argc, char *argv[]) { int i = 1024; int *p2 = &i; int **p3 = &p2; cout<<p2<<endl; //p2的地址 cout<<*p3<<endl; //*p3所指向的 正是p2的地址 cout<<i<<endl; cout<<*p2<<endl; cout<<**p3<<endl; }
p2 指向 i 的地址
p3 指向 p2的地址
所以前两个输出结果是一样的
0x7fff8775fef4 0x7fff8775fef4 1024 1024 1024
(以下示例摘自网络)
看这样一段程序
int m_value = 1; void func(int *p) { p = &m_value; } int main(int argc, char *argv[]) { int n = 2; int *pn = &n; cout << *pn << endl; func(pn); cout << *pn <<endl; return 0; }
输出结果
2 2
第二次输出时,结果为2.
指针在进行参数传递时,把他所指向的数据复制了一份,传入函数,所以他只传递了这个值,所以在函数结束之后,指针仍然指向原来的 2
如果要想让指针在函数之后改变,则可以用指针的指针进行参数传递
int m_value = 1; void func(int **p) { *p = &m_value; } int main(int argc, char *argv[]) { int n = 2; int *pn = &n; cout << *pn << endl; func(&pn); cout << *pn <<endl; return 0; }
改动之后,函数 func 传入的参数是 *p 的地址 也就是 &pn 既然地址传进去了,就可以相应的改变地址保存的数据了
所以改动之后输出结果是
2 1
再看一下指针的引用
int m_value = 1; void func(int *&p) { p = &m_value; } int main(int argc, char *argv[]) { int n = 2; int *pn = &n; cout << *pn << endl; func(pn); cout << *pn <<endl; return 0; }
输出结果
2 1