引用格式一个已存在变量的别名,通过这个别名就可以用来修改指向的变量的值。引用和指针很像,在很多情况下就是简化版的指针。引用比指针弱的地方在于引用必须在创建时初始化,并且不能再改变指向的对象,而指针可以为空,也可以改变指向的内存地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
int () { int a = 10 ; int &b = a; int *p = &a; *p = 20 ; std ::cout << "a = " << a << std ::endl ; b = 30 ; std ::cout << "a = " << a << " , b = " << b << std ::endl ; int c; int &bb = b; bb = 40 ; std ::cout << "a = " << a << " , b = " << b << " , bb = " << bb << std ::endl ; return 0 ; }
引用的使用方式 typename &b = a, & 符号前有符号表示引用,否则表示取地址
引用是一种关系申明,表示它和某个变量的关系,它们类型相同,并共享一片内存
引用一经申明就不可以修改
可以引用一个引用
引用作为函数参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
struct Person { char name[50 ]; int age; }; void printfA (Person *p) ;void printfB (Person &p) ;void printfC (Person p) ;int () { Person person = {"aaaa" , 18 }; std ::cout << "==========参数为指针类型==========" << std ::endl ; printfA(&person); std ::cout << "third time = " << person.age << std ::endl ; std ::cout << "==========参数为引用类型==========" << std ::endl ; printfB(person); std ::cout << "third time = " << person.age << std ::endl ; std ::cout << "==========参数为结构体类型==========" << std ::endl ; printfC(person); std ::cout << "third time = " << person.age << std ::endl ; return 0 ; } void printfA (Person *p) { std ::cout << "first time = " << p->age << std ::endl ; p->age = 20 ; std ::cout << "second time = " << p->age << std ::endl ; } void printfB (Person &p) { std ::cout << "first time = " << p.age << std ::endl ; p.age = 30 ; std ::cout << "second time = " << p.age << std ::endl ; } void printfC (Person p) { std ::cout << "first time = " << p.age << std ::endl ; p.age = 40 ; std ::cout << "second time = " << p.age << std ::endl ; }
1 2 3 4 5 6 7 8 9 10 11 12
==========参数为指针类型========== first time = 18 second time = 20 third time = 20 ==========参数为引用类型========== first time = 20 second time = 30 third time = 30 ==========参数为结构体类型========== first time = 30 second time = 40 third time = 30
以上这段代码分别将一个结构体用指针形式、引用形式和结构体变量形式作为形参传入到函数中,并对其值进行修改,最后打印结果。
我们可以看到指针类型和引用类型对变量进行修改,因为它们都指向同一块内存。结构体类型,形参的修改在栈区上,并不会对堆区中的结构体变量本身产生影响。
注:关于堆区、栈区的内存四区概念有问题可以看 C语言学习笔记-指针01 。
引用是一个变量的别名,有时候起到和指针一样的效果
引用比指针具有更强的可读性
引用作为函数返回值
若返回栈变量: 不能成为其它引用的初始值(不能作为左值使用)
若返回静态变量或全局变量: 可以成为其他引用的初始值(可作为右值使用,也可作为左值使用)
引用作为函数返回-值返回栈变量代码示例
引用作为函数返回-值返回静态变量代码示例
指针引用
都在代码里了,关键代码如下,点击查看完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
int getTeacher (Teacher **teacher) { Teacher *t = NULL ; t = (Teacher*)malloc (sizeof (Teacher)); if (t == NULL ) { return -1 ; } strcpy (t->name, "Mary" ); t->age = 30 ; *teacher = t; return 0 ; } int getTeacher02 (Teacher *&teacher) { teacher = (Teacher *)malloc (sizeof (Teacher)); if (teacher == NULL ) { return -1 ; } strcpy (teacher->name, "Lucy" ); teacher->age = 20 ; return 0 ; }
const 引用
const 最常见的作用就是在变量作为函数形参的时候加上 const 修饰,起到对形参的保护作用,加了 const 修饰的参数就不会在函数中被修改。
const 如果和引用放在一起会擦出什么火花?
1 2 3 4 5 6 7 8
const int a = 10 ;const int &b = a;int c = 20 ;const int &d = c;c = 30 ;
第一组代码想说明的是 const 修饰的常量,如果我想用一直普通的引用指向它是不可以的。假设我们可以用一个普通的 b 做为 a 的引用,那就可以使用 b 去修改 a 所指代的内存,而 a 指向的内存是被 const 保护的,是不允许修改的。不过我们可以使用 const 修饰的引用去指向 a,此时他们的安全级别一样,都不会导致内存被修改的安全问题。
第二组代码想说明的 const 修饰的引用安全级别更高,可以用安全级别高的去引用安全级别低的。这时候造成的现象是 d 被 const 修饰不能修改,而 c 任然可以修改,虽然是同一片内存但是 d 也无法阻止 c 进行修改。
1 2 3 4
void printA (const Teacher &teacher) { printf ("teacher.age:%d n" , teacher.age); }
上面这段代码则表示 const 修饰的形参是只读的,不允许在函数中进行修改,起到了保护形参的作用。
总结一下:
const 引用可以指向安全级别比其低的或者同级的
const 引用常在形参传递过程中起保护形参的作用
近期评论