C# 值类型和引用类型及参数传递
值类型和引用类型:
C#数据类型分为两大类:值类型和引用类型。
值类型数据主要有:结构体struct,枚举体enum,布尔型bool,浮点型,整型。
引用类型数据主要有:数组,字符串,接口,委托,类。
值类型和引用类型的区别:
引用类型继承自System.Object,值类型继承自System.ValueType。
引用类型保存到内存的堆heap中,值类型保存在内存的堆栈stack中。在.net中,栈的内存是自动释放的,而堆会有垃圾回收器GC来释放。
引用类型可以派生出新的类型,而值类型不可以。引用类型可以包含null值,而值类型不可以。
引用类型变量赋值只复制对象的引用,不复制对象本身。而将一个值类型变量赋给另一个值类型变量时,将复制包含的值。
下面一个小例子可以简单说明值类型和引用类型:
- class PointR
- {
- public int x, y;
- }
- struct PointV
- {
- public int a, b;
- }
- class Program
- {
- static void Main(string[] args)
- {
- //给一个引用类型赋值将复制到一个对象的引用,而给一个值类型赋值将复制一个对象的值
- PointR r;
- PointV v;
- r = new PointR();
- v = new PointV();
- r.x = ;
- v.a = ;
- PointR pr = r;
- PointV pv = v;
- pr.x = ;
- pv.a = ;
- Console.WriteLine(r.x);//
- Console.WriteLine(v.a);//
- Console.Read();
- }
- }
C#参数传递:
.net默认的是通过值传送变量,但是也可以迫使值参数通过引用传送给方法。C#要求对传递给方法的参数进行初始化。在传递给方法之前,无论时按值传递,还是按引用传递,变量都必须初始化。 ref关键字:可以迫使值参数通过引用传送给方法。即:在.net中,如果把一个参数传递给方法,且这个方法的输入参数前带有ref关键字,则该方法对变量所做的任何改变都会影响原来对象的值。下面一个小例子说明按值传递和ref参数传递:
- class Program
- {
- //默认值,C#的参数是按值传递的,这也是最常见的情况
- static void Method1(int p)
- {
- ++p;
- }
- //为了按引用传递,C#提供了参数修饰字ref,。ref修饰字要求变量在传递给方法之前必须赋值
- static void Method2(ref int p)
- {
- ++p;
- }
- static void Main(string[] args)
- {
- int x = ;
- int y = ;
- Method1(x);
- Method2(ref y);
- Console.WriteLine(x);//
- Console.WriteLine(y);//
- Console.Read();
- }
- }
在方法的输入参数前面加上out关键字时,传递给该方法的变量可以不初始化。该变量通过引用传递,所以在从被调用的方法中返回时,方法对该变量进行的任何改变都会保留下来。在调用该方法时,还需要使用out关键字,这与在定义该方法时一样。并且out修饰字要求变量在从方法返回时必须赋值。举例说明:
- class Program
- {
- //out修饰字要求变量在从方法返回时必须赋值
- static void Split(string name, out string firstName, out string lastName)
- {
- int i = name.LastIndexOf(' ');
- firstName = name.Substring(, i);
- lastName = name.Substring(i + );
- }
- static void Main(string[] args)
- {
- string a, b;
- Split("zhou enlai", out a, out b);
- Console.WriteLine("{0}+ {1}", a, b);//zhou+ erlai
- Console.Read();
- }
- }
还有一个params修饰传递参数,不多说,直接举例:
- class Program
- {
- //params 修饰字可以使用在方法的最后一个参数上,这样方法就可以接受任意数目的某种类型的参数
- static int Add(params int[] arr)
- {
- int sum = ;
- foreach (int i in arr)
- {
- sum += i;
- }
- return sum;
- }
- static void Main(string[] args)
- {
- int i = Add(, , , , , , );
- Console.WriteLine(i);//
- Console.Read();
- }
- }
补充:
起因是网上看到一句话:java里面的参数传递都是按值传递的。不理解,于是查询资料:
java数据类型分类两大类:基本类型和对象类型,相应的,变量也分为基本类型和引用类型。
基本类型数据有:byte\short\int\long\float\double\char\boolean
整数类型:byte是8位字节,范围是-128-127,short是16位的,int是32位,long是64位
浮点数:float是32位,1位符号位,7位指数,23位有效尾数;double是64位,1位符号位,11位指数,52位有效尾数;
字符:char是16位字节
布尔类型:boolean。
基本类型的变量保存本身的数值,“引用值”则保存内存空间地址,代表了对某个对象的引用,而不是对象本身。
基本类型的变量在声明时则由系统自动分配内存空间,不能包含null;而引用类型的变量在声明时仅仅是对变量分配了引用空间,而不分配数据空间,可以赋予null值。
值传递:
值传递在进行方法调用时,实际参数把它的值传递给对应的形参,函数接收的形参数组其实是实参数值的拷贝,对形参进行修改不会影响实际参数的数值。
引用传递:
引用传递在进行方法调用时,实际参数把它对对象的引用传递给形参变量,而不是将对象传递给形参变量,在进行方法调用过程中,实参变量和形参变量具有相同的数值,都是指向同一块内存地址,对形参数值进行改变,改变的是内存地址中的实际对象,形参变量本身的引用数值不会得到改变。
此处需要考虑String、Integer、Double等基本基本类型包装类,它们都是immutable类型,因为它们都没有自身修改操作的函数,所以对它们的每次操作都是重新创建一个对象,因此可以将它们当作基本类型使用,在参数传递时可以按照值传递来考虑。
综合,上文说的java都是按值传递的,可以这么理解,这个值传递其实是实参地址的拷贝,得到这个拷贝地址后,你可以通过它修改这个地址的内容,因为此时这个内容的地址和原地址是同一个地址,但是你不能修改这个地址本身使其重新引用其它的对象,所以也可以说成是指传递。但同时因为形参的引用地址和实参的引用地址是相同的,因此对形参的修改也会影响实参变量。
说明:不管是对象、基本类型还是对象数组、基本类型数组,在函数中都不能改变其实际地址但能改变其中的内容。
这里加入一张网上拷贝的图片便于理解:
关于值传递和引用传递,网上还有这么一种说法:其实都是对“=”的理解
1、= 是赋值操作(任何包含=的如+=、-=、 /=等等,都内含了赋值操作)。不再是你以前理解的数学含义了,而+ - * /和 = 在java中更不是一个级别,换句话说, = 是一个动作,一个可以改变内存状态的操作,一个可以改变变量的符号,而+ - * /却不会。这里的赋值操作其实是包含了两个意思:1、放弃了原有的值或引用;2得到了 = 右侧变量的值或引用。Java中对 = 的理解很重要啊!!可惜好多人忽略了,或者理解了却没深思过。
2、对于基本数据类型变量,= 操作是完整地复制了变量的值。换句话说,“=之后,你我已无关联”;至于基本数据类型,就不在这科普了。基本类型:Byte\Short\int\long\float\double\char\boolean.
3、对于非基本数据类型变量,= 操作是复制了变量的引用。换句话说,“嘿,= 左侧的变量,你丫别给我瞎动!咱俩现在是一根绳上的蚂蚱,除非你再被 = 一次放弃现有的引用!!上面说了 = 是一个动作,所以我把 = 当作动词用啦!”。而非基本数据类型变量你基本上可以
4、参数本身是变量,参数传递本质就是一种 = 操作。参数是变量,所有我们对变量的操作、变量能有的行为,参数都有。所以把C语言里参数是传值啊、传指针啊的那套理论全忘掉,参数传递就是 = 操作。
C# 值类型和引用类型及参数传递的更多相关文章
- C#学习笔记(三):值类型、引用类型及参数传递
值类型和引用类型简介 C#中存在两种数据类型,分别是值类型与引用类型,下面我们来看看这两种类型的区别. 值类型主要包括: 简单类型(如int.float.char等,注意string不是值类型): 枚 ...
- 枚举|标志枚举+|(或)和&(与)运算|类型转换|值类型和引用类型|传参|异常|垃圾回收
枚举部分 enum 关键字用于声明枚举,即一种由一组称为枚举数列表的命名常量组成的独特类型. 通常情况下,最好是在命名空间内直接定义枚举,以便该命名空间中的所有类都能够同样方便地访问它. 但是,还可以 ...
- 值类型与引用类型(特殊的string) Typeof和GetType() 静态和非静态使用 参数传递 相关知识
学习大神博客链接: http://www.cnblogs.com/zhili/category/421637.html 一 值类型与引用类型 需要注意的string 是特殊类型的引用类型. 使用方法: ...
- .NET的堆和栈02,值类型和引用类型参数传递以及内存分配
在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...
- .NET面试题解析(01)-值类型与引用类型
系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 常见面试题目: 1. 值类型和引用类型的区别? 2. 结构和类的区别? 3. delegate是引用类型还 ...
- 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]
原文地址:http://www.cnblogs.com/xy8.cn/articles/1227228.html 一.栈和托管堆 通用类型系统(CTS)区分两种基本类型:值类型和引用类型.它 ...
- C#中的基元类型、值类型和引用类型
C# 中的基元类型.值类型和引用类型 1. 基元类型(Primitive Type) 编译器直接支持的类型称为基元类型.基元类型可以直接映射到 FCL 中存在的类型.例如,int a = 10 中的 ...
- JavaScript中值类型与引用类型
JavaScript中的变量类型有哪些? 值类型:字符串(string).数值(number).布尔值(boolean).null.undefined 引用类型:对象(Object).数组(Array ...
- js中的值类型和引用类型的区别
1.JavaScript中的变量类型有哪些? (1)值类型(基本类型):字符串(String).数值(Number).布尔值(Boolean).Undefined.Null (这5种基本数据类型是按 ...
随机推荐
- ArcEngine开发:IElement.Geometry 值不在预期范围内 + 元素绘制代码
IElement pEle = pLineEle as IElement; pEle.Geometry = pLn; pLn为一个ILine对象,想当然的以为它是IGeometry对象,可以赋值,结果 ...
- style在进行图形绘制前,要设置好绘图的样式
是html5出现的新标签,像所有的dom对象一样它有自己本身的属性.方法和事件,其中就有绘图的方法,js能够调用它来进行绘图 ,最近在研读<html5与css3权威指南>下面对其中最好玩的 ...
- GC、LOH和Performance相关
Performance Now that we have a basic model for how things are working, let's consider some things th ...
- 【新产品发布】【GK101 10MHz任意波发生器】
简介: GK101 10MHz掌上任意波形发生器基于多项先进技术,在较小的体积上实现了普通台式仪器才具有的功能.仪器仅手掌大小,实现了80M采样率.10MHz最大频率.10Vpp最高幅度的输出. 仪器 ...
- YII2.0 secruity
保存密码不能用明文保存,用MD5或者sha1哈希化是安全,但是随着硬件的发展,可能会暴力破解,目前能够对抗暴力破解的哈希算法是 bcrypt,Yii提供了两个帮助函数使用crypt进行安全的哈希加密 ...
- iOS coreData使用遇到的问题
使用coreData,一定要有上下文环境.创建上下文时,和以前有些不同,之前 NSManagedObjeContext *context = [NSManagedObjectContext alloc ...
- nodejs:本地文件夹http服务器http-server
一.已经安装nodejs的电脑,有一个方便通过http访问本地文件夹.文件夹服务器 static files over HTTP,并不是我们平常说的node那个web服务器哦 二.好处 可以方便实现跨 ...
- java list<int>报错
请问一下在java中的List<int> list=new List<int>();这条语句的两个int处会报错,请问为什么? 答: 两处错误:第一:List是接口,需要实现类 ...
- 【FFXV】中物理模拟的结构以及游戏业界的乐趣
11月2日是在日本兵库县神户会议中心召开的[SIGGRAPH ASIA 2015]的第一天,在游戏开发专门的研究会[R&D in the Video Game Industry]上,展开了[F ...
- (一)win7下cocos2d-x 21 + vs2010
1.下载SDK http://cocos2d.cocoachina.com/download,我下载2.1版本,cocos2d-2.1rc0-x-2.1.2-hotfix.zip @ Apr.08, ...