首页 > 代码库 > 内存(传值、传址、传引用)

内存(传值、传址、传引用)


前言:


          最近对内存产生了兴趣、全是因为马士兵老师的一句Master key、马上要考二级了、大题构造函数比较多、形参有 int & x  这么写的、也有int *x 这么写的、还有普通 int x这么写的、我的乖乖这都是传的什么?


           int x 是 传值、int *x  是传址、 int & x是传引用、那这三者传参数都有什么区别呢?


下面就用三个例子讲解


          声明:下面堆栈的图其实是不正确的、八个基本类型(byte、short、int、long、char、float、double、boolean)都是在栈里面的、而下面的int型我把名字看做栈里面、里面的数值看做是堆里面的、只是为了大家明白传值、址、引用、的区别。


<span style="font-size:18px;">// C_TEST.cpp : Defines the entry point for the console application.
//
//
#include "stdafx.h"
#include "iostream"
using namespace std;//我是在VS2008里面作的调试,这里需要导入命名空间STD
</span>




传值


<span style="font-size:18px;">//传值
	void swap1(int x,int y)
	{
		X = 3
		Y = 4
		cout<<"     传值函数输出:    "<<x<<"     "<<y<<endl;
		
		
	}
	void main()//入口点
	{
	 int a(1);
	 int b(2);
	swap1(a,b);
	cout<<"     外界值:      "<<a<<"     "<<b<<endl;
	
	}
	
//输出:
	//传值函数输出:3 4
	//外界值: 1 2
</span>



堆栈图(执行swap1前、执行swap1后)




           

          是把实参的值赋值给行参   、那么对行参的修改,不会影响实参的值   。


          简单的说就是、栈里面的地址、堆里面的对象都不是一个、比如我有首《chenchen绝唱》这首歌、我拷给了我的好同桌许小乖、她觉得特难听、立马就删了、她删了歌、我这还有、互不影响、还有一点要说明的就是、栈里存放着指向对象的地址、所以对象复制出来是一样的、但是堆里的地址不一样、所以ab栈的地址与xy栈的地址不一样、就好似我的歌放在我的硬盘里、考给同桌的歌放在她的硬盘里、物理地址不一样。





传址


这里把x、y做了交换、因为是传址、所以更改了a 、b指向堆里面的对象。


//传址
	void swap2(int *x,int *y) //传址调用
	{
	 //把主函数里数据的地址传了过来
	 //这里改变了数据的地址,在主函数里打印出a,b的时候,当然就发生了交换!
	   int temp;
	   temp = *x;
	   *x = *y;
	   *y = temp;
	   cout<<"     传址函数内:    "<<x<<"     "<<y<<endl;
	}
	void main()//入口点
	{
	 int a(1);
	 int b(2);
	swap2(&a,&b);
	cout<<"     外界值:      "<<a<<"     "<<b<<endl;
	
	}
//输出:
	//传址函数输出:0016FE04 0016FDF8
	//外界值: 2 1


这里打印了x y 是 内存 地址、交换操作却是对堆里对象的操作。


堆栈图(执行swap2前、执行swap2后)




       

       是传值的一种特殊方式,只是他传递的是地址,不是普通的如int   


          
那么传地址以后,实参和行参都指向同一个对象   


          对x、y的操作、互换、其实就是对a、b值的互换、因为他们都指向同一个对象、打个比方、有两张一模一样的藏宝图、你一张、我一张、但是宝藏只有一个、我找到宝藏、拿走了、你再过去拿宝藏就没有了、所以传址只是把地址传过来、用的对象还是那个对象、所以x y值的互换就是 对象 1 和2 值的互换、但是ab的指向的地址没变、堆里两个对象的值却互换了。





传引用


<span style="font-size:18px;">//引用
void swap3(int &x,int &y)//传引用
{
 //加了&之后,用地址引用了主函数里面的数据值,说明x,y 的地址是a,b的地址~~,因而主函数里面的a,b发生交换~~
   int temp;
   temp = x;
   x = y;
   y = temp;
   cout<<"     换址函数内:    "<<x<<"     "<<y<<endl;
}

void main()//入口点
{
 int a(1);
 int b(2);
 swap3(a,b);
cout<<"     外界值:      "<<a<<"     "<<b<<endl;

}

//输出:
	//传址函数输出:21
	//外界值: 2 1
</span>



堆栈图(执行swap3前、执行swap3后)





          这里的图有可能不太对、但是我能这么理解了、打个比方吧、一人拿着一张藏宝图叫我去找宝藏、藏宝图给了我、我去把宝藏拿给他、上图栈里的x y应该是指向a b 或者是a b的别名。


-----------------------------------------------------------------------------------

函数调用角度SEE  
    
  
传值:

    
  
传值:
   
            
函数参数压栈的是参数的副本。
   
            
任何的修改是在副本上作用,没有作用在原来的变量上。
   
    
  
传指针:
   
            
压栈的是指针变量的副本。
   
            
当你对指针解指针操作时,其值是指向原来的那个变量,所以对原来变量操作。
   
    
  
传引用:
   
            
压栈的是引用的副本。由于引用是指向某个变量的,对引用的操作其实就是对他指向的变量的操作。(作用          和传指针一样,只是引用少了解指针的草纸)
  

-----------------------------------------------------------------------------------


总结:

         这两天学了内存发现挺有意思的、说是换真还是一头雾水、不是特别清楚、但是感觉真的对分析程序很有帮助、基础知识嘛、要好好学。




参考文章

          http://blog.csdn.net/juliababy/article/details/2837646

         http://blog.csdn.net/aristolto/article/details/7262738



——————————————— 困-困 ———————————————


——————————chenchen——————————


内存(传值、传址、传引用)