A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王盛 中级黑马   /  2013-6-12 08:58  /  1704 人查看  /  13 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王盛 于 2013-6-12 15:50 编辑

谁能总结一下 值传递和引用传递? 感激不尽

13 个回复

倒序浏览
C#值类型数据直接在他自身分配到的内存中存储数据,而C#引用类型只是包含指向存储数据位置的指针。值类型保存在堆栈中,引用类型将它的值保存在托管堆中,在堆栈中保存的是对堆上地址的引用,在方法中传递参数时,所有类型都是传递堆栈中的位置,具体过程为先在堆栈上复制一个传递的对象,然后将该对象传给参数,所以显而易见,数值类型保存在堆栈中,作为参数传递时直接复制了数值的一个副本给方法,方法对该副本所做的任何操作都不会影响到该数值的原值,但是引用类型复制的是堆栈上对堆的引用,该引用指向的仍然是堆上的引用类型,所以对应用类型所做的操作都会引起其本身的改变。
回复 使用道具 举报
c#的数据类型分为 值类型 和  引用类型
               
值类型包括基本类型(数值类型,bool类型等)、结构和枚举
引用类型包括 类、委托、数组等

数据类型在内存中的保存时,值类型保存在堆栈中,
                          引用类型将它的值保存在托管堆中,在堆栈中保存的是对堆上地址的引用

在方法中传递参数时,所有类型都是传递堆栈中的位置
数值类型保存在堆栈中,作为参数传递时直接复制了数值的一个副本给方法,方法对该副本所做的任何操作都不会影响到该数值的原值,但是原值此时已经无效,副本为有效值
但是引用类型复制的是堆栈上对堆的引用,该引用指向的仍然是堆上的引用类型,所以对应用类型所做的操作都会引起其本身的改变
回复 使用道具 举报
out是什么传递, 我只知道 ref是 引用传递。。。。。
回复 使用道具 举报
值传递指的是方法被调用时传递进来的参数是一个副本(拷贝),而不是传递进来参数本身。
换句话说对值传递参数的修改不会影响到调用方传递的参数对象;
而引用传递指的是方法被调用时传递进来的参数是一个引用,换句话说传递进来的参数是指向调用方传递的参数本身的。
对引用传递的参数的修改会影响到调用方传递的参数对象。
回复 使用道具 举报
简单来说,值传递就是把自身的值“复制一遍”传给另一个变量,如果改变另一个变量的值,那么自身的值没有影响。引用传递是把自身的值“直接”传递给另一个变量,如果改变另一个变量的值,就是在改变自身的值。
回复 使用道具 举报
引用类型作为参数时:
1、在修改变量本身时,结果类似于值传递,即不会改变传递前的变量的值
2、在修改变量的属性或字段时,才是引用传递,会影响到传递前的变量的值
3、参数使用了ref后,才是真正的引用传递,不管修改变量本身还是修改变量的属性或字段,都会影响到传递前的变量的值

值传递:传的是对象的值拷贝。(即函数内参数对象是调用时传递的对象的栈中对象的拷贝。)
引用传递:传的是栈中对象的地址。(即函数内参数对象与调用时传递的对象完全是同一栈中对象。)
回复 使用道具 举报
参数传递分值传递和引用传递两种。
通常,在没有显式指出ref和out时都是值传递。

值传递:传的是对象的值拷贝。(即函数内参数对象是调用时传递对象的栈中对象的拷贝。)
引用传递:传的是栈中对象的地址。(即函数内参数对象与调用时传递对象完全是同一栈中对象。)
回复 使用道具 举报
彭康 中级黑马 2013-6-12 10:54:20
9#
值传递 和 引用传递分别对应 值类型和引用类型
值传递是赋值的时候将栈里的数值完全复制一份一模一样的给新对象
引用传递是将新对象的栈指针指向赋值着的堆内存
回复 使用道具 举报
王盛 发表于 2013-6-12 09:40
out是什么传递, 我只知道 ref是 引用传递。。。。。

out和ref都是引用传递。
只不过使用ref型传递参数时,传入的参数必须先被初始化。
但对out而言,可以在方法中对其完成初始化。
具体请详见:
http://www.cnblogs.com/xiangshu/articles/2054188.html
回复 使用道具 举报
好的  明白了  。。。  谢谢啦~!
回复 使用道具 举报
正好整理了以前的笔记就发现了这个就过来说说~~~~~~~~~~
       在C#语言中,符合公共语言规范(CLS)的数据类型可分为两类:值类型和引用类型。这两者有很大的区别,其中值类型变量直接保存变量的值,引用类型的变量保存的是数据的引用地址。当把一个值变量赋给另一个值变量,会在堆栈中保存两个完全相同的值,每个变量都有自己的值,因此对一个变量的操作不会影响到其他变量;而把一个引用变量赋给另一个引用变量,则会在堆栈中保存对同一堆位置的两个引用,对一个变量的数据进行操作就是对这个变量在堆栈中的数据进行操作,另一个变量也跟着改变。
1、值类型:

(1)简单类型:是由一系列元素构成数据类型。(整数、布尔、字符、实数)

①整数类型:
   sbyte   有符号8位整数   在-128到127之间
   byte    无符号8位整数   在0到255之间
   short   有符号16位整数  在-32768至32767之间
   ushort   无符号16位整数  在0到65535之间
   int    有符号32位整数    在-2147483648到2147483647之间
   uint    无符号32位整数    在0到4294967625之间
   long    有符号64位整数    在-.........到.........之间
   ulong   无符号64位整数    在0到.........之间

(2)布尔类型:在其它整数类型和布尔类型之间不存在任何转换。在c#中只存在“true”和“false”的写法。

(3)实数类型:

<1>浮点类型:单精度(float)与双精度(double),其中双精度(double)获得的结果更为精确,但是占用内存单位过大。
 取值范围:●单精度:正负1.5*10(-45次方)到3.4*10(38次方)之间,精度为7位数。
      ●双精度:正负5.0*10(-324次方)到1.7*10(308次方)之间,精度为15到16位数。

<2>十进制类型(decimal):是一种高精度128位数据类型,表示的范围从1.0*10(-28次方)到7.9*10(28次方)的28至29位有效数字。比双精度更精确,但范围很小。
 当定义一个decimal变量并赋值给它时,使用m下标以表时它是一个十进制类型。
 如:decimal d_value=1.0m
  如果省略了m,在变量被赋值之前,它将被编译器当作双精度类型来处理。

④字符类型:通过十六进制转义符(前缀\x)或unicode表示法给字符型变量赋值(前缀\u)。
  如:char c='\x0032'; //
      char c='\u0032'; //
转义符:
 \' 单引号  \'' 双引号 \\ 反斜杠 \o 空字符 \a 感叹号(alert) \b 退格
 \f 换 页  \n 新 页  \r 回车  \t 水平(table) \v 垂直(table)

(2)结构类型:把一系列相关的变量组织成为一个单一的实体的过程,这个单一实体的类型就叫结构类型,每个类型称为结构成员。
  采用struct来声明结构类型。
  结构类型包含的成员没有限制,可以相同,也可以不相同。
(3)枚举类型:为一组在逻辑上密不可分的整数值提供便于记忆的符号。
  采用enum来声明枚举类型。
  注:按照系统的默认,枚举中的每个元素类型都是int型,且第一个元素删去的值为0,它后面的每个连续的元素的值按加1递增,在枚举中,也可以给元素直接赋值。
  如:enum weekday
         sunday=1,monday,tuesday,wednesday,...,...,...,
       };
   为枚举的元素所赋的值的类型限于:long、int、short、byte等整数类型。
2、引用类型

    该类型的变量不直接存储所包含的值,而是指向它所要存储的值。
c#中的引用类型有四种:
◆类
◆委托
◆数组
◆接口

(1)类:是面向对象编程的基本单位,是一种包含数据成员、函数成员和嵌套类型的数据结构。
  ●数据成员:常量、域、事件。
  ●函数成员:方法、属性、索引指示器、运算符、构造函数、析构函数。
  注:类支持继承机制,通过继承,派生类可以扩展基类的数据成员和函数方法,进而达到代码重用和设计重用的目的。

①object类:
  是所有其它类型的基类,c#中所有类型都直接或间接地从object类中继承,因此,可以对object的变量赋予任何类型的值。
  对object类型的变量声明用object关键字。

②string类:c#还定义了一个基本的类string,专门用于字符串的操作。

(2)委托(delegate):在声明委托时,只需要指定委托指向的原型的类型,它不能有返回值,也不能带有输出类型的参数。
  如:delegate int mydelegate();

(3)数组:是一组类型相同的有序数据,数组按照数组名、数据元素的类型和维数来进行描述。

     
回复 使用道具 举报
值传递  传递的是值类型的一个副本,对传递后的值的操作不会改变原值
引用传递  传递的是指向存在堆的数据的一个栈上的引用,得到的引用和原引用都指向同一个堆存的数据,所以通过传递的引用对堆数据的修改其实修改的就是原值。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马