文章目录
-
变量名回顾
-
c++中的引用
-
const常引用:
-
那么如何修改const引用的值那?
- const常引用 用常量初始化
-
引用有自己的存储空间吗?
-
引用在C++中的内部实现是一个常指针
-
证据
-
当函数返回值为引用时
-
C++对三目运算符做了什么?
变量名回顾
c++中的引用
在C++中新增加了引用的概念
引用可以看作一个已定义变量的别名
引用的语法:Type& name = var;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 1#include <stdio.h>
2
3int main(int argc, char *argv[])
4{
5 int a = 4;
6 int& b = a; //定义引用
7
8 b = 5;
9
10 printf("a = %d\n", a);
11 printf("b = %d\n", b);
12 printf("&a = %08X\n", &a);
13 printf("&b = %08X\n", &b); //
14
15 printf("Press enter to continue ...");
16 getchar();
17 return 0;
18}
19
20
运行结果:
注意:普通引用在声明时必须用其它的变量进行初始化。
引用的意义:
引用作为其它变量的别名而存在,因此在一些场合可以代替指针
引用相对于指针来说具有更好的可读性和实用性
注意:
引用作为函数参数声明时不进行初始化。
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 1#include <stdio.h>
2
3void swap(int& a, int& b)
4{
5 int t = a;
6 a = b;
7 b = t;
8}
9
10int main(int argc, char *argv[])
11{
12 int a = 4;
13 int b = 5;
14
15 swap(a, b);
16
17 printf("a = %d\n", a);
18 printf("b = %d\n", b);
19
20 printf("Press enter to continue ...");
21 getchar();
22 return 0;
23}
24
25
const常引用:
在C++中可以声明const引用
const Type& name = var;
const引用让变量拥有只读属性(不能出现在赋值符号的左边)
1
2
3
4
5
6
7
8
9
10
11
12
13 1#include <stdio.h>
2int main()
3{
4 int a = 4;
5 const int& b = a;
6
7 b = 5; //error
8
9 printf("a = %d\n", a);
10 printf("b = %d\n", b);
11}
12
13
那么如何修改const引用的值那?
A:用指针
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 1#include <stdio.h>
2int main()
3{
4 int a = 4;
5 const int& b = a;
6
7 int* p = (int*)&b;
8
9 //b = 5; //error
10 *p = 5;
11
12 printf("a = %d\n", a);
13 printf("b = %d\n", b);
14}
15
16
const常引用 用常量初始化
当使用常量对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
1
2
3
4
5
6
7
8
9
10
11
12 1#include <stdio.h>
2
3int main()
4{
5 const int& b = 1;
6
7// b = 5; //error
8
9 printf("b = %d\n", b);
10}
11
12
Tip:
使用常量对const引用初始化后将生成一个只读变量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 1#include <stdio.h>
2
3int main()
4{
5 const int& b = 1;
6
7 int* p = (int*)&b;
8
9// b = 5; //error
10 *p = 5;
11
12 printf("b = %d\n", b);
13}
14
15
引用有自己的存储空间吗?
引用既然是变量的别名,那么引用有自己的存储空间吗?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1#include <stdio.h>
2
3struct TRef
4{
5 int& a;
6 int& b;
7};
8
9int main(int argc, char *argv[])
10{
11 printf("sizeof(TRef) = %d\n", sizeof(TRef));
12
13 printf("Press enter to continue ...");
14 getchar();
15 return 0;
16}
17
18
运行结果:
分析:证明引用有自己的存储空间。
引用在C++中的内部实现是一个常指针
Type& name <- -> Type* const name
Improtance:
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏。
1
2
3
4
5
6
7
8
9
10
11
12
13 1void f(int& a)
2{
3 a = 5;
4}
5
6//等价于
7
8void f(int* const a)
9{
10 *a = 5;
11}
12
13
证据
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 1#include <iostream>
2using namespace std;
3
4struct TRef{
5 int& a;
6 int& b;
7 int& c;
8};
9
10int main()
11{
12 int a;
13 int b;
14 int c;
15
16 TRef rA = {a,b,c};
17
18 cout << &a << endl;
19 cout << &b << endl;
20 cout << &c << endl; //a,b,c的内存地址是连续的,相差4字节
21
22 cout << &rA << endl; //&rA与&c相差恰好12个字节
23 cout << sizeof(TRef) <<endl; //12
24
25 return 0;
26}
27
28
29
当函数返回值为引用时
若返回栈变量
不能成为其它引用的初始值
不能作为左值使用
若返回静态变量或全局变量
可以成为其他引用的初始值
即可作为右值使用,也可作为左值使用
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 1#include <stdio.h>
2
3int& f()
4{
5 static int a = 0;
6
7 return a;
8}
9
10int& g()
11{
12 int a = 0;
13
14 return a; //[Warning] reference to local variable 'a' returned [-Wreturn-local-addr]
15}
16
17int main()
18{
19 int a = g();
20 int& b = g(); //局部变量不能成为其它引用的初始值 此处b的值将是随机的
21
22 f() = 10;
23
24 printf("a = %d\n", a);
25 printf("b = %d\n", b);
26 printf("f() = %d\n", f());
27
28 printf("Press enter to continue ...");
29 getchar();
30 return 0;
31}
32
33
tips:
引用的实质是指针,返回局部变量的引用相当于 返回局部变量的指针。
C++对三目运算符做了什么?
当三目运算符的可能返回都是变量时,返回的是变量引用
当三目运算符的可能返回中有常量时,返回的是值
1
2
3
4
5
6
7
8 1int a = 1;
2int b = 2;
3(a < b ? a : b) = 3; //正确,返回a或b的引用,可以作为左值使用
4
5(a < b ? 11 : b) = 3; //错误,可能返回中有常量,返回的是值,不能作为左值使用
6
7
8