您现在的位置: 万盛学电脑网 >> 程序编程 >> 网络编程 >> 编程语言综合 >> 正文

C#中按引用传递与按值传递的区别,以及ref与out关键字的用法详解

作者:佚名    责任编辑:admin    更新时间:2022-06-22

以下是对C#中按引用传递与按值传递的区别,以及ref与out关键字的用法进行了详细的分析介绍,需要的朋友可以过来参考下   复制代码 代码如下:
/给三个整数从小到大排序并求和及其平均值
//其中,三个待求整数及其排序的结果由引用参数传递;其和由输出参数传递;平均值由返回值返回。
//在Main()方法中实现三个待求整数的输入及结果的输出
//目的:定义方法;调用方法;;理解形参和实参的引用传递关系;熟悉引用参数和输出参数的使用。
using System;
class Class1
 {
   //x,y,z是形参,按值传递
   static void Sort(int x, int y, int z)
    {
      int temp=0;
      if(x>y)
       {
         temp=x;
         x=y;
         y=temp;
       }
      if(y>z)
       {
         temp=z;
         z=y;
         if(x>temp)
          {
            y=x;
            x=temp;
          }
         else
          {
            y=temp;
          }
       }
       Console.WriteLine("The sorted list is {0},{1},{2}",x,y,z);
       x=x+y+z;
    }

   //i,j,k,total是形参,按引用传递(ref参数,out参数,都是按引用传递的方式)
   static double Average(ref int i, ref int j, ref int k, out int total)
    {
      double l = 0;
      total = i+j+k;
      i=total;
      l=(double)(total/3.0);
      return l;
    }

   static void Main()
    {
      //a,b,c是实参,将要赋值给形参i,j,k,total;
      int a, b, c;

      //声明out参数result,可以不用初始化它
      int result;

      Console.Write("Please enter the first number a =");
      a = Convert.ToInt32(Console.ReadLine());
      Console.Write("Please enter the second number b =");
      b = Convert.ToInt32(Console.ReadLine());
      Console.Write("Please enter the third number c =");
      c = Convert.ToInt32(Console.ReadLine());     

      Sort(a,b,c);

      //Sort(int x, int y, int z)函数中,形参x,y,z是按值传递的,所以即使函数中有x=x+y+z;函数      //执行后实参a值不变。
      Console.WriteLine("The original value of /"a/" is {0}, it hadn't been changed in spite "+"of manipulating the Sort() method, because it is transmitted by a Value para /"x/"!",a);

      //Average(ref int i, ref int j, ref int k, out int total)函数中,形参a,b,c,result都是        //按引用传递的,执行后实参a值改变。
      Console.WriteLine("The average result is {0}",Average(ref a,ref b,ref c, out result));
      //ref参数在调用方法前必须几经初始化。
      //而out参数在调用方法前可以没有初始化,他们都以引用传递方式传递

      Console.WriteLine("The value of /"a/" has been changed due to the Average() method"    +" is manipulated, and it is transmitted by a ref para /"ref i/"! now it is {0}!",a);

      Console.ReadLine();
    }
 }


问题与解答:

1,值传递时,为什么被调用的方法中的形参值的改变不会影响到相应的实参?
答:因为按值传递时,系统首先为被调用的方法的形参分配内存空间,然后把实参中的值按位置一一对应“复制”给形参。形参中存储的值只是一份实参的拷贝,因此被调用方法中形参值的任何改变都不会影响到相应的形参。

2,值传递和引用传递有什么不同,什么是值参数,它以什么方式传递?
答:值 传递时,系统首先为被调用方法的形参分配内存空间,并将实参的值按位置一一对应地复制给形参,此后,被调用方法中形参值得任何改变都不会影响到相应的实 参; 而引用传递时,系统不是将实参本身的值复制后传递给形参,而是将其引用值(即地址值)传递给形参,因此,形参所引用的该地址上的变量与传递的实参相同,方 法体内相应形参值得任何改变都将影响到作为引用传递的实参。

3,什么是形参,什么是实参?
答:
形参:
在定义函数中指定的参数就是形参,在未出现函数调用时,他们并不占内存中的存储单元,只有在发生函数调用时,函数中的形参才被分配内存单元。在调用结束后,形参所占的内存单元也被释放。

实参:实参可以是常量、变量和表达式,但要求有确定的值。在调用时将实参的值赋给形参。在内存中,实参单元和形参单元是不同的单元。在调用函数时,给形参分配存储单元,并将实参对应的值传递给形参,调用结束后,形参单元被释放,实参单元仍保留原值。

理解:
实参就是送进去方法中的东西~~行参就是把送进来的东西在方法中进行拷贝加工,加工完后方法就返回一个东西--返回值。

值传递的时候,实参是不变的~形参是随着计算而变化的~~
指针/引用传递的时候~~行参怎么变~实参就怎么变.... 

参数的传递分为:1.值方式参数传递,2.引用方式参数传递。
1)按值传递(不能改变实参)
实参是变量,表达式等数值。

函数调用的时候,实参和形参存在于内存中2快不同的区域,实参先自己复制一份拷贝,再把拷贝传给形参。由于是传递的是拷贝,所以实参不会受形参的影响,实参值不会被改变。

2)按地址传递(可以改变实参)
实参是指针/引用。

函数调用的时候,指针传给你,形参和实参指针都一样,对形参的任何操作就等于对实参的操做。实参的值就可以被改变。

对参数的影响:
2种数据类型:值类型+引用类型
2种传参方式:值传参+引用传参(ref与out关键字);

以上的四种参数的组合 除了值传参方式传递值类型数据,其他的组合方式对参数的操作都会影响参数,都会改变!

值类型:简单类型(int,float,double,long,char,bool)+结构+枚举
存储结构:数据存放在栈中(栈:先进后出;单入口,单出口);效率高
赋值方式:传的是值

引用类型:除去简单类型(int,float,double)+结构+枚举以外的类型都是引用数据类型。如string;object;类;数组;委托;接口...
存储结构:栈中存地址;堆中放数据;
赋值方式:传的是数据的地址。