传值、传址和传引用
先上一实例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
3My age is 24
In this , my age is 25
Now my age is 24
大家都是age,但是打印出来的值,又是24,又是25.
请把地址给我
绕开“值传递”问题的第一种方法是向函数传递变量的地址取代它的值。我们说C语言强大,有很大一部分就是在于他的灵活,他的灵活,有大一部分就是可以利用指针进行委婉地乱改。。。
正如我们所理解的,想要获取某个变量的地址只需要在它前边加上一个“取地址”操作符(&)就行了。
传过去一个地址,接收也是一个地址
1 | #include <iostream> |
输出1
2
3My 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 | #include <iostream> |