长安的花

当学问走过漫漫古道
凿刻入千窟,心也从愚昧中苏醒

0%

c++学习08-传值传址传引用

传值、传址和传引用

先上一实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

void changeAge( int age, int newAge );

// 如果想要实现计划功能,需要怎么改?

main()
{
int age = 24;
std::cout << "My age is " << age << "\n";

changeAge( age, age+1 );

std::cout << "Now my age is " << age << "\n";
}

void changeAge( int age, int newAge )
{
age = newAge;
std::cout << "In this , my age is " << age << "\n";
}

输出
1
2
3
My age is 24
In this , my age is 25
Now my age is 24

大家都是age,但是打印出来的值,又是24,又是25.

请把地址给我

  • 绕开“值传递”问题的第一种方法是向函数传递变量的地址取代它的值。我们说C语言强大,有很大一部分就是在于他的灵活,他的灵活,有大一部分就是可以利用指针进行委婉地乱改。。。

  • 正如我们所理解的,想要获取某个变量的地址只需要在它前边加上一个“取地址”操作符(&)就行了。

  • 传过去一个地址,接收也是一个地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

void changeAge( int *age, int newAge );

// 如果想要实现计划功能,需要怎么改?

main()
{
int age = 24;
std::cout << "My age is " << age << "\n";

changeAge( &age, age+1 );

std::cout << "Now my age is " << age << "\n";
}

void changeAge( int *age, int newAge )
{
*age = newAge;
std::cout << "In this , my age is " << *age << "\n";
}

输出

1
2
3
My age is 24
In this , my age is 25
Now my age is 25

  • 非完璧归赵

  • 注意:如果传过去的是地址,在函数中必须要通过“*”对指针进行解引用,除非你有其他用途

swap

传统方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

void swap( int *x, int *y );

main()
{
int x, y;

std::cout << "输入两个不同的值";
std::cin >> x >> y;

swap( &x, &y );

std::cout << "调换后输出" << x << ' ' << y << "\n\n";
}

void swap( int *x, int *y )
{
int temp;
temp = *x; //传统方法
*x = *y;
*y = temp;
}

第二种方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>

void swap( int *x, int *y );

main()
{
int x, y;

std::cout << "请输入两个不同的值:";
std::cin >> x >> y;

swap( &x, &y );

std::cout << "调换后输出:" << x << ' ' << y << "\n\n";
}

void swap( int *x, int *y )
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}

这里用得是异或,这里需要解释一下:

  • 任意变量x与自身异或结果为0,即:x^x = 0
  • 任意变量x与0进行异或运算,结果不变,即:x^0 = x
  • 异或运算的结合性:a^b^c = (a^b)^c = a^(b^c)
  • 异或运算的交换性:a^b = b^a

再来解释上面的交换为什么可行:

新a = 旧a^旧b

这时候新a里含有 旧a和旧b

新b = 新a^旧b —> 新b = (旧a^旧b)^旧b = 旧a^(旧b^旧b) = 旧a^0 = 旧a,完成了旧a的值交给新b的过程。
新新a = 新a^新b —> 新新a = (旧a^旧b)^新b= (旧a^旧b)^旧a = (旧b^旧a)^旧a = 旧b^(旧a^旧a) = 旧b^0 = 旧b 完成了旧b的值交给新新a的过程。

引用传递

传址在我们看来已经是很不错,不过C++语言的大神们在完善的过程中完善了地址这个概念。

设想:如果事先就知道某个函数的参数只能接受一个地址,能不能使用某种约定使得在调用该函数时不需要使用指针的语法呢?

于是乎,以“引用传递方式”传递“输入方式”的概念因此而产生了。

其实他跟我们这个传址的目的是一样的,都是把地址传递给函数,但语法不同更加容易使用了。

在声明的时候就说了我要一个地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

void swap( int &x, int &y );//声明的时候就说了,我要的是一个地址

main()
{
int x, y;

std::cout << "请输入两个不同的值:";
std::cin >> x >> y;

swap( x, y );

std::cout << "调换后输出:" << x << ' ' << y << "\n\n";
}

void swap( int &x, int &y )
{
int temp;
temp = x;
x = y;
y = temp;
}
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道