很多刚入门c++的计算机小白,在面露难色学完指针后再接触C++中的引用。就会有一种十分舒适的感觉。在c++中引用无论如何都是在某些方面替代指针的容易上手的工具。引用通俗一点就是别名,而指针是涉及计算机底层内存的地址。当然既然是工具我们就得深入了解引用。引用的实质还是指针常量,只不过更加“平易近人”
首先让我们复习以下***指针常量***
指针常量特点:指针的指向不可以修改,但是指针指向的值可以修改,后面两字可修改
#include<iostream> using namespace std; int main() { int a = 10; int b = 10; int* p = &a;//定义一个指针p指向a的地址。 //指针常量特点:指针的指向不可以修改,但是指针指向的值可以修改, int* const p2 = &a;//定义一个指针常量p2指向a的地址。 //p2 = &b //错误,因为指针指向不可修改 *p2 = 20; //正确,指针指向的值可以修改。 system("pause"); return 0; }
这里就不画内存条详细解释了。>_<
根据指针常量的特点:
引用必须初始化
引用一旦初始化以后便不可修改
a = 10; b = 20; int &c = a; //这就是将引用c初始化。 //int &c 错误 c = b /*!!!!这并不是更改引用,而是赋值操作。 即a及a的别名c均重新变成了20*/
结合指针常量这也是非常好理解的。(也许你并不想提这几个字)@- _ @-。
可以实现指针传递的功能并代替指针。我们知道引用的实质,但在我们用的时候。我们只需要考虑这就是个别名
#include<iostream> using namespace std; //值传递。只可改变形式参数,不可改变实参。 void hanshu_1(int a, int b){ int temp = a; a = b; b = temp; } //地址传递。可改变实参。 void hanshu_2(int* a, int* b){ int temp = *a; *a = *b; *b = temp; } //引用传递。也可改变实参,更加通俗易懂。 void hanshu_3(int &a, int &b){ int temp = a; a = b; b = temp; } int main(){ int a = 10; int b = 20; //值传递 hanshu_1(a,b); cout<<"a与b的值是"<<a<<";"<<b<<endl;//不会交换 //地址传递 hanshu_2(&a,&b); cout<<"a与b的值是"<<a<<";"<<b<<endl;//会交换 //引用传递 hanshu_3(a,b); cout<<"a与b的值是"<<a<<";"<<b<<endl;//会交换 }
#include<iostream> using namespace std; int& hanshu(){ int a = 10; return a } int main(){ int &test = hanshu(); cout << test << endl;//第一次返回系统会默认帮你保存局部变量a的值 cout << test << endl;//栈区中的a已被释放,不会返回 10 }
上面的函数有问题。具体可自己尝试。
栈区的基部概念:
栈区数据由编译器管理开辟与释放:
注意!不要在函数中返回局部变量的地址。因为局部变量存放在栈区,数据在函数执行完后会自动释放。
#include<iostream> using namespace std; int& hanshu(){ static int a = 10;//静态变量存放在堆区。 return a } int main(){ int &test = hanshu(); hanshu() = 1000;//左值即在等号的左边 /*此时a与test均变为1000 因为返回的是引用,就相当于a赋值为1000! */ }
!!!以防万一,将来如果出错,在上万行代码中找bug很恐怖@-_@-
void hanshu_1(const int& a){ cout<<a<<endl; }
因为引用本身需要一个合法的内存空间。结合指针不可以对一个没有指向的指针所指向的量进行赋值。
int &a = 10;//错误,因为引用本身需要一个合法的内存空间。
但是下面的可行。更简洁因为编译器帮我们作了相应的处理使其合法。
即帮我们创建了一个临时变量来存储10,再引用。
const int &a = 10;
关于引用就总结这么多了,谢谢大家阅读。
推荐自学C++的课程,哔哩哔哩up黑马程序员,个人感觉课程十分nice
点击这里