C++基础Day12
Day12.2021.11.19
注意事项:
-
引用必须初始化
-
初始化后不可以改变
//引用必须初始化 int a = 10; int b = 20; int& c = a;//int &c;是不允许的 ? c = b;//引用是改变不了的,这句话是赋值操作,把b指向那块内存赋值给c指向的内存 cout << a << endl;//20 cout << b << endl;//20 cout << c << endl;//20
引用本质应该是一个指针常量,指针指向的值可修改,指向的内存地址不能改变
引用传递
函数传参时,使用引用简化指针让形参修饰实参
//值传递 void swap1(int a, int b) { int index = a; a = b; b = index; cout << "a=" << a << endl; cout << "b=" << b << endl; } //地址传递 void swap2(int* a, int* b) { int index = *a; *a = *b; *b = index; cout << "a=" << *a << endl; cout << "b=" << *b << endl; } //引用传递 //引用传递是起别名,别名和本名指向同一块内存,引用传参相当于把自身传进去改 void swap3(int& a,int& b) { int index = a; a = b; b = index; cout << "a=" << a << endl; cout << "b=" << b << endl; } int main() { int a = 10; int b = 20; swap1(a, b); cout << a << endl;//10 cout << b << endl;//20 ? int c = 30; int d = 40; swap2(&c, &d); cout << c << endl;//40 cout << d << endl;//30 ? int e = 50; int f = 60; swap3(e, f); cout << e << endl;//60 cout << f << endl;//50 ? system("pause"); return 0; }
引用做函数返回值
注意:不要返回局部变量引用
用法:函数调用作为左值
//不要返回局部变量的引用 int& test1() { int a = 10; return a; } int& test2() { static int a = 10; return a; } int main() { ? int& b = test1(); cout << b << endl;//第一次编译器做保留 cout << b << endl;//栈区的局部变量内存被释放掉了 //这里面做了两次引用,test2()是a的别名,c是test2()的别名,实际上c和test2()都是a int& c = test2(); cout << c << endl; cout << c << endl; //函数调用可以作为左值 test2() = 100; cout << "c=" << c << endl; cout << "test2()=" << test2() << endl; //如果函数的返回值是引用,则函数可以作为左值 }
引用的本质
是指针常量
void fun(int& ref) { ref = 100;//实际上是 *ref=100; } int main() { int a = 10; //引用的本质是一个指针常量 //写成 int* const ref= &a;实际上就是创建了一个指针ref指向a,并且指针指向不可以改 int& ref = a; ? ref = 20; ? cout << "a=" << a << endl;//20 cout << "ref=" << ref << endl;//20 ? fun(a); cout << "a=" << a << endl;//100 cout << "ref=" << ref << endl;//100 }
常量引用
修饰形参,防止误操作
int main() { ? int a = 10; ? //int& b = 10;必须引用一块合法的内存空间(这个常量10没开辟空间) ? //加了const之后,编译器把代码修改为 //int temp=10;const int& b=temp; 原名不知道 const int& b = 10; //b = 20;因为加了const,所以不能修改值 }
实际场景
void showNum(int& num) { ? num = 10000;//不希望改动 cout <<"num=" << num << endl; } ? int main() { int num = 10; showNum(num); }
代码多的时候容易把实参改了,所以加个const
1.需要首先明确的是,形参改变实参这种情况只可能发生在地址传递或引用传递之中。这里针对的是引用传递的情况;
2. 防止形参改变实参”的意思是:在函数中可能会对形参的值进行修改,由于是引用传递,因此实参也会跟着改变。但是我们有时又不想让实参跟着改变,那么就可以用const来修饰形参。
那么,如果改变形参时不想同时改变实参,为什么不在一开始就使用值传递呢?
这是因为值传递在数据量大的时候会消耗大量的内存,而引用传递可以大大降低内存的使用。
而不加引用,编译器会在函数中给形参也开辟和实参相同大小的空间,这样会占用更多内存。