1.引用的几个错误用法:
1 #include<iostream> 2 using namespace std; 3 int main() { 4 int sum = 0, val = 1; 5 int &ref;//错误引用必须初始化 6 int &ref = 10;//错误引用必须与一个对象绑定,不能与字面值绑定 7 int &ref = sum+val;//错误引用不能与表达式的结果绑定在一起 8 &ref = val;//错误引用绑定了另外一个对象 9 ref = val;//正确这只是一个赋值 10 return 0; 11 }
其他注意事项:
1.对引用的任何操作都是对对象进行操作
2.不能定义引用的引用(不过好像也没法写出来)
2.引用VS指针
1.引用不是对象,而指针是。(对象是具有某种数据类型的内存空间,它有实际的地址和存储空间)。引用就像一个贴贴纸,这个贴贴纸贴到盒子(变量)上,为盒子起了一个别名,并且无法撕下来了;指针就像一个盒子(对象都可以认为是一个盒子)装了变量的地址,你也可以将盒子里的东西拿出来再装其他地址。
1 int a = 10; 2 int& r1 = a; 3 int& r2 = r1;//这样做是可以的,就像a这个盒子多了一个贴贴纸,多了一个别名
2.普通的引用(常量的引用除外)和指针必须绑定或则指向与自身类型相同的变量
1 double dval = 3.14; 2 int& r1 = dval;//错误 3 int* p1 = dval;//错误
3.引用必须要初始化,而指针不用(野指针,此时指针指向一个不确定的值),因此,不存在指向空值的引用这个事实意味着使用引用的代码效率比使用指针的要高。因为在使用之前不需要测试它的合法性。
1 void printInt(const int& ri) 2 { 3 cout<<ri<<endl;//不需要测试ri,它肯定指向一个int值 4 } 5 //vs 6 void printInt(const int *pi) 7 { 8 if(pi) return; 9 }
4.引用不可以先后指向不同的值(绑定),指针可以(拷贝)。
5.引用没有实际的地址,指针有,因此不能定义指向引用的指针。
6.sizeof指针永远是8个字节(64位操作系统),sizeof引用结果是引用的变量的类型大小。
7.能用引用的地方尽量用引用。
8.只有指针的引用(相当于该指针的别名),没有引用的指针,因为引用本身不是一个对象,没有实际地址。
1 int i = 42; 2 int* p;//p是一个int类型的指针 3 int*& r = p;//r是一个引用,是一个对指针p的引用 4 r = &i;//r引用了一个指针,因此给r赋值&i就是令p指向i 5 *r = 0;//相当于将i的值改成0
9.想理解r的类型到底是什么,办法是从右向左读r的定义。离变量名最近的符号(&)对变量有直接的影响,因此r是一个引用,其余的部分用来确定r引用的类型是什么,此例中*说明r引用的是一个指针。
1 int a = 10; 2 int* const ai = &a; 3 const int* aj = &a; 4 const int* const ak = &a; 5 6 //aii是一个指针,它是一个指向“int* const”的指针 7 int* const* aii = &ai; 8 //ajj是一个指针,它是一个指向“const int*”的指针 9 const int** ajj = &aj; 10 //akk是一个指针,它是一个指向“const int* const”的指针 11 //注意akk同样可以指向“const int*”“int* const”,但其他两个只能指向自己类型 12 const int* const* akk = &ak; 13 14 cout << "&a=" << &a << endl; 15 cout << "&ai=" << &ai << endl; 16 cout << "&aj=" << &aj << endl; 17 cout << "&ak=" << &ak << endl; 18 19 cout << "aii=" << aii << endl; 20 cout << "ajj=" << ajj << endl; 21 cout << "akk=" << akk << endl; 22 23 cout << "*aii=" << *aii << endl; 24 cout << "*ajj=" << *ajj << endl; 25 cout << "*akk=" << *akk << endl; 26 27 cout << "**aii=" << **aii << endl; 28 cout << "**ajj=" << **ajj << endl; 29 cout << "**akk=" << **akk << endl;
10.实参是指针它指向了一块内存,形参也是同级指针,即便形参在其所在的函数中指向了另一块内存,实参的指针指向依然不变,相当于值传递
1 void test(int* p) 2 { 3 int a = 1; 4 p = &a; 5 cout << p << " " << *p << endl; 6 } 7 int main(void) 8 { 9 int* pt = NULL; 10 test(pt); 11 if (pt == NULL) 12 cout << "指针pt为NULL" << endl; 13 return 0; 14 }
地址传递时,形参指针在其所在函数内没有实现对*p的赋值,实参就不会改变
1 void testPTR(int* p) { 2 int a = 12; 3 p = &a; 4 5 } 6 7 void main() 8 { 9 int aa = 10; 10 testPTR(&aa); 11 cout << aa << endl; 12 }
结果是10
实参是引用它指向了一个变量,形参也是引用,形参在其所在的函数中指向了另一个变量,实参的指针指向虽然依然不变,但实参的值以及实参所指向的变量的值发生了改变
1 void test(int& p) 2 { 3 int a = 1; 4 p = a; 5 cout << "a:" << a << endl; 6 cout << "p:" << p << endl; 7 } 8 int main() 9 { 10 int aa = 10; 11 int& pp = aa; 12 cout << "aa:" << aa << endl; 13 cout << "pp:" << pp << endl; 14 test(pp); 15 cout << "aa:" << aa << endl; 16 cout << "pp:" << pp << endl; 17 return 0; 18 }