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

前言:

最近对内存产生了兴趣、全是因为马士兵老师的一句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——————————

时间: 2024-10-29 00:35:18

内存(传值、传址、传引用)的相关文章

Js 赋值传值和引用传址

赋值传值和引用传址 在JavaScript中基本数据类型都是赋值传值,复合数据类型都是引用传址(传地址) ? 基本数据类型的变量名和数据是直接存在"快速内存"(栈内存)中,而复合数据类型(对象和数组)的存储分两个部分:实际数据存在"慢速内存"(堆内存)中,栈内存中只存变量名和数据在堆内存中的位置(地址)

JS 基础知识2 传值和传址

要知道传址跟传址,首先我们先了解下数据值的操作. 1复制:可以把它赋值给一个新的变量 2传递:可以将他传递给一个函数或者方法 3比较:可以与另外一个值比较,判断是否相等 简要介绍下传值: 当一个数据是通过值被操作的,那么关系到的是数据的值,在赋值的过程中,是对实际值进行了COPY,储存在一个变量或者属性或数组中,copy的值与原数据是相互独立的. 当数据通过值传递给一个函数时,数据的一份传递给这个函数,如果函数体修改了这个值,只在函数体受影响,函数外的原数据不受影响. 当一个数据通过值和另外一个

Python 函数参数引用(传值/传址)/copy/deepcopy

精简版: 传值:被调函数局部变量改变不会影响主调函数局部变量 传址:被调函数局部变量改变会影响主调函数局部变量 Python参数传递方式:传递对象引用(传值和传址的混合方式),如果是数字,字符串,元组则传值:如果是列表,字典则传址: copy使用场景:列表或字典,且内部元素为数字,字符串或元组 deepcopy使用场景:列表或字典,且内部元素包含列表或字典 完整版: 1.传值和传址的区别 传值就是传入一个参数的值,传址就是传入一个参数的地址,也就是内存的地址(相当于指针).他们的区别是如果函数里

js学习笔记&lt;拷贝传值,引用传址和匿名函数&gt;

拷贝传值:把一个变量的值拷贝一份,传给了另外一个变量拷贝传值中,两个变量之间没有任何联系,修改其中一个一个变量的值,原来的变量不变. 例: var arr1 = ["张三",24,"大专"]; //定义一个二维数组:   var arr2 = arr1;//将arr1的地址传给arr2,(不传递实际参数)   arr1[1] = 30;//改变arr1中的24等于30:   alert(arr2[1]);//输出arr2[1]; 引用传址: 例: var arr =

js 的复制和引用 (传值和传址)

复制(传值-实参):  基本类型赋值.函数参数 引用(传址-形参):  对象.数组.函数

传值、传址和传引用

在编写个人函数的时候,你将受到C++中一条基本原则的限制:在默认的情况下,参数只能以值传递的方式给函数.这句话的理解是:被传递到函数的只是变量的值,永远不会是变量本身.举例如下: #include <iostream> void changeAge( int age, int newAge ); // 如果想要实现计划功能,需要怎么改? main() { int age = 24; std::cout << "My age is " << age &

javascript的变量,传值和传址,参数之间关系

先把收获晾一下: 1.javascrip变量包含两种类型的值,一种为引用类型的值,一种是基本类型的值.引用类型包括:Array,Object,Function(可以这么理解,非基本类型的都是引用类型);5种基本类型包括:undefined,null,string,boolean,number 2.函数的参数的传递的机制是复制变量值. 书上说:”把函数外部的值复制给函数内部的参数,就和把值从一个变量复制给另一个变量一样.基本类型的传递如同基本类型变量的复制一样,而引用类型的则如同引用类型变量的复制

他山之石,calling by share——python中既不是传址也不是传值

事情是这样的,Python里是传址还是传值令人疑惑,限于本人没有C基础,所以对大家的各类水平层次不一的解答难以确信. 第一个阶段: 在读<python基础教程第二版>的时候感到疑惑,然后群友解答(略敷衍),接着就是知乎上提问(感谢大家的热心回答,但我很晚才收到推送) 虽然是某天早晨睡不着,翻看公众号的时候看见一篇<不要再问 "Python 函数中,参数是传值,还是传引用?" 这种没有意义的问题了>的文章,初步释疑惑(但后来我觉得他的说法虽然形象,但是不准确) 第

[javaSE] 变量的传值与传址

变量:就是将不确定的数据进行存储.也就是需要在内存中开辟一个空间 这个空间需要一个名称,这个名称就是变量名 基本数据类型:byte,short,int,long,double,float,char,boolean 引用数据类型:类(Class),接口(interface),集合 传值就是把这个变量复制一份 传址就是还是同一个对象 基本数据类型一般都是传值,引用数据类型一般是传地址 import java.util.ArrayList; import java.util.List; public