引用变量

引用变量

被 palabos 倒逼学 C++。

1 引用变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
int main()
{
using namespace std;
int rats = 101;
int & rodents = rats; // 一个 int 类型的引用

cout << "rats = " << rats;
cout << ", rodents = " << rodents << endl;
rodents++;
cout << "rats = " << rats;
cout << ", rodents = " << rodents << endl;

cout << "rats address = " << &rats;
cout << ", rodents address = " << &rodents << endl;
// 两个地址的值是一样的
return 0;
}

rats 和 rodents 指向相同的值和内存单元。引用创建的时候就得赋值。引用应该只和一个变量相关联,不然会有意想不到的问题:

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
// secref.cpp -- defining and using a reference
#include <iostream>
int main()
{
using namespace std;
int rats = 101;
int & rodents = rats;

cout << "rats = " << rats;
cout << ", rodents = " << rodents << endl;

cout << "rats address = " << &rats;
cout << ", rodents address = " << &rodents << endl;

int bunnies = 50;
rodents = bunnies;
cout << "bunnies = " << bunnies;
cout << ", rats = " << rats;
cout << ", rodents = " << rodents << endl;

cout << "bunnies address = " << &bunnies;
cout << ", rodents address = " << &rodents << endl;
// cin.get();
return 0;
}

输出结果:

1
2
3
4
rats = 101, rodents = 101
rats address = 0x61fe14, rodents address = 0x61fe14
bunnies = 50, rats = 50, rodents = 50
bunnies address = 0x61fe10, rodents address = 0x61fe14

1-1 引用用作函数参数

引用作为函数的参数,使得函数中的变量名成为程序中变量名的别名。函数可以访问调用函数中的变量。

常引用

如果想让函数使用传递给它的信息,有不能修改信息,可以使用 常引用。这个时候编译器发现函数试图修改信息,就会生成错误消息。
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
#include <iostream>
double cube(double a);
double refcube(double const &ra); // const 关键字放在 “类型名” 前面后面都可以
int main ()
{
using namespace std;
double x = 3.0;

cout << cube(x);
cout << " = cube of " << x << endl;
cout << " = cube of " << refcube(x) << endl;
// cin.get();
return 0;
}

double cube(double a)
{
a *= a * a;
return a;
}

double refcube(const double &ra)
{
int a;
a = ra * ra * ra;
return a;
}

1-2 引用用于结构 和 类对象

是为了处理 “结构” 和 “类” 这些用户定义的类型。

函数返回引用

返回一个作为参数传递给函数的引用。作为参数的引用指向函数使用的数据,所以返回的引用也指向这些数据。
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
59
60
61
62
63
64
65
66
67
68
69
//strc_ref.cpp -- using structure references
#include <iostream>
#include <string>
struct free_throws
{
std::string name;
int made;
int attempts;
float percent;
};

void display(const free_throws & ft);
void set_pc(free_throws & ft);
free_throws & accumulate(free_throws &target, const free_throws &source);

int main()
{
free_throws one = {"Ifelsa Branch", 13, 14};
free_throws two = {"Andor Knott", 10, 16};
free_throws three = {"Minnie Max", 7, 9};
free_throws four = {"Whily Looper", 5, 9};
free_throws five = {"Long Long", 6, 14};
free_throws team = {"Throwgoods", 0, 0};
free_throws dup;
set_pc(one);
display(one);
accumulate(team, one);
display(team);
// 返回一个作为参数传递给函数的引用
display(accumulate(team, two));
accumulate(accumulate(team, three), four);
display(team);
// 返回一个作为参数传递给函数的引用
dup = accumulate(team,five); // 结构直接赋值了
std::cout << "Displaying team:\n";
display(team);
std::cout << "Displaying dup after assignment:\n";
display(dup);
set_pc(four);
// ill-advised assignment
accumulate(dup,five) = four; // 左边返回的 dup 被修改了
std::cout << "Displaying dup after ill-advised assignment:\n";
display(dup);
return 0;
}

void display(const free_throws & ft)
{
using std::cout;
cout << "Name: " << ft.name << '\n';
cout << " Made: " << ft.made << '\t';
cout << "Attempts: " << ft.attempts << '\t';
cout << "Percent: " << ft.percent << '\n';
}
void set_pc(free_throws & ft)
{
if (ft.attempts != 0)
ft.percent = 100.0f *float(ft.made)/float(ft.attempts);
else
ft.percent = 0;
}

free_throws & accumulate(free_throws & target, const free_throws & source)
{
target.attempts += source.attempts;
target.made += source.made;
set_pc(target);
return target;
}

引用用于类对象

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
#include <iostream>
#include <string>
using namespace std;
string version1(const string & s1, const string & s2);
const string & version2(string & s1, const string & s2);

int main()
{
string input;
string copy;
string result;

cout << "Enter a string: ";
getline(cin, input);
copy = input;
cout << "Your string as entered: " << input << endl;
result = version1(input, "***");
cout << "Your string enhanced: " << result << endl;
cout << "Your original string: " << input << endl;

result = version2(input, "###");
cout << "Your string enhanced: " << result << endl;
cout << "Your original string: " << input << endl;

return 0;
}

string version1(const string & s1, const string & s2)
{
string temp;

temp = s2 + s1 + s2;
return temp;
}

const string & version2(string & s1, const string & s2) // has side effect
{
s1 = s2 + s1 + s2;
return s1;
}

不能返回一个作用域在函数中,函数结束,它就自动销毁的对象。

作者

缪红林

发布于

2021-06-08

更新于

2021-06-09

许可协议

评论