天天看点

C++值传递(包含指针传递),引用传递

参考:http://blog.sina.com.cn/s/blog_673ef8130100imsp.html

1:指针传递

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(这里是在说实参指针本身的地址值不会变,但是如果对这个地址所指向的数据进行修改,那么实际上就会反应到全局变量中)

2:引用传递

而在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址(int &a的形式)。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。

引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

为了进一步加深大家对指针和引用的区别,下面我从编译的角度来阐述它们之间的区别:

程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

3:

无论你传值还是传指针,函数都会生成一个临时变量,

但传引用时,不会生成临时变量,

当你传值时,只可以引用值而不可以改变值,但传值引用时,可以改变值,

当你传指针时,只可以改变指针所指的内容,不可以改变指针本身,但传指针引用时,既可以改变指针所指的内容,又可以改变指针本身,

但传引用主要是它不生成临时变量,不进行返回值copy等,速度快。

4:实例point.cpp

#include <iostream>

using namespace std;

void func1(int a) {
	a ++;
}

void func2(int &a) {
	a ++;
}

void func3(int *a) {
	cout<<"func3:"<<a<<endl;
	*a = *a + 1;
}


class A{
private:
	int a;
public:
	A(int a) {this->a = a;}
	int get_a() {
		return a;
	}
};

void func4(A &a) {
	cout<<a.get_a()<<endl;
}

int main() {

	int a = 2;
	func1(a);
	cout<<a<<endl;
	func2(a);
	cout<<a<<endl;
	int *b;
	b = &a;
	cout<<b<<endl;
	func3(b);
	cout<<b<<endl;
	cout<<a<<endl;
	cout<<*b<<endl;
	cout<<"-----"<<endl;

	func2(*b);
	cout<<*b<<endl;

	cout<<"-----"<<endl;
	A *aa = new A(4);
	func4(*aa);	
}