值参数、引用参数、输出参数、数据参数

 

using System;
using System.Collections.Generic;
using System.Text;

namespace Method
{
    /*
     * 方法中的参数:
     * 值参数
     * 引用型参数
     * 输出参数
     * 数组型参数
     */
    class Method
    {
        #region 值参数
        // 当利用值向方法传递参数时,编译程序给实参的值做一份拷贝,并且将此拷贝传递给该方法。被调用的方法不会修改内存中实参的值,所以使用值参数时,可以保证实际值是安全的
        //static void Main(string[] args)
        //{
        //    int i = 1;
        //    int j = 2;
        //    Swap(i, j);
        //    Console.WriteLine("i={0},j={1}", i, j);//i=1,j=2
        //    Console.ReadKey();
        //}
        //static void Swap(int x, int y)
        //{
        //    int temp = x;
        //    x = y;
        //    y = temp;
        //}

        #endregion

        #region 引用型参数
        //引用型参数并不开辟新的内存区域。当利用引用型参数向方法传递形参时,编译程序将把实际值在内存中的地址传递给方法
        //static void Main(string[] args)
        //{
        //    int i = 1;
        //    int j = 2;
        //    Swap(ref i, ref j);
        //    Console.WriteLine("i={0},j={1}", i, j);//i=2,j=1
        //    Console.ReadKey();
        //}
        //static void Swap(ref int x, ref int y)
        //{
        //    int temp = x;
        //    x = y;
        //    y = temp;
        //}


        #region 引言

        //引用 http://topic.csdn.net/u/20090724/00/0373897c-2258-44f9-9d50-c8f7458dd488.html
        //如果有个函数
        //void func(int n)
        //{
        //  n = 100;
        //}
        //调用这个函数的时候
        //int i = 1;
        //func(i);
        //调用之后i还是1
        //这大概就是楼主说的形参和实参问题。

        //如果这样定义
        //void func(ref int n)
        //{
        //  n = 100;
        //}
        //然后这样调用
        //int i = 1;
        //func(ref i);
        //调用之后i就被改成100了
        //对于这个函数void func(int n) 
        //这属于值传递,调用func(i)的时候,会把i拷贝一个副本,然后把这个副本传给func函数。
        //func函数里面的n,和外面的i,就完全没有关系了。所以修改n不影响i

        //void func(ref int n)
        //这属于引用传递,调用func(ref i)的时候,直接把i的地址传给func函数。
        //func函数里面的n,和外面的i,完全就是同一个地址的同一个变量


        //注:

        //出现在函数定义中的参数称为形式参数,简称形参。出现在函数调用中的参数称为实际参数,简称实参。 


        //说明:(1)形参在未调用时,不占内存 

        //(2)实参必须有确定的值,若形参是数组名时,传递数组的首地址 

        //(3)定义时,必须指定形参类型 

        //(4)实参类型应与形参赋值兼容,且类型不同时在调用前必须作原型声明。 

        //(5)实参和形参的数据传递是单向的值传递,实参和形参占不同内存单元,地址不同。(可以参见引用的例子)

        //形参在调用函数时开始分配内存

        #endregion

        #region 其它
        //在方法中作用引用型参数,会经常可以导致多个变量名指向同一个内存地址:
        static string s;
        static void other(ref string a, ref string b)
        {
            s = "one";
            a = "two";
            b = "three";
            Console.WriteLine("s={0},a={1},b={2}", s, a, b);//i=2,j=1
            Console.ReadKey();
        }

        static void other2()
        {
            other(ref s, ref s);
        }
        static void Main(string[] args)
        {
            other2();
        }
        #endregion
        #endregion

        #region 输出参数
        输出型参数也不开辟新的内存区域,与引用型参数的差别在于,调用方法前无需对变量进行初始化,
        //static void SplitPath(string p, out string s1, out string s2, ref int j)
        //{
        //    int i = p.Length;
        //    while (i > 0)
        //    {
               
        //        char ch = p[i - 1];
        //        if (ch == '\\' || ch == '/' || ch == ':')
        //        {
        //            break;  
        //        }
        //        i--;
        //    }
        //    j = i;
        //    s1 = p.Substring(0, i);
        //    s2 = p.Substring(i);
        //}
        //static void Main(string[] args)
        //{
        //    string a, b;
        //    int j = 0;
        //    SplitPath("c:/Windows/System/hello.text", out  a, out b, ref j);
        //    Console.WriteLine("please write a={0},b={1},j={2}",a,b,j);
        //    Console.ReadKey();
        //}
        #endregion

        #region out 与 return 的区别
        /*
         * out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值
         * return会引起函数退出,并返回变量   变量必须赋值
         * return返回的值需要接收      out会改变原由变量
         *
         */
        #endregion

        #region 测试  out 与 ref 改变参数本身,使用out、ref测试传递值类型与引用类型
        //public static string n;
        //public static int a = 3;
        //public static void Main(string[] args)
        //{
        //    Console.WriteLine(n);
        //    Method.name(out n);
        //    Console.WriteLine(n);

        //    Console.WriteLine(a);
        //    Method.num(out a);
        //    Console.WriteLine(a);

        //    Console.ReadKey();
        //}
        //public static string  name(out string name)
        //{
        //    name = "zhangsan";
        //    return name;
        //}

        //public static void num(out int num)
        //{
        //    num = 2;
        //}

        以下两个方法行不通,当方法名相同,参数相同,返回值不同,被编译器认为是定义了相同的成员
        public static int ceshi(string a,int b)
        {
            return 1;
        }
        public static string ceshi(string a, int b)
        {
            return "1";
        }

        #endregion

        //相关文章:http://www.cnblogs.com/andy-g/archive/2010/09/28/1837544.html  c# 值类型与引用类型 实参与形参 ref与out
        //http://msdn.microsoft.com/zh-cn/library/szasx730(v=VS.80).aspx 使用ref和out传递数组

        #region 使用ref和out传递数组

        //static void giveValue(ref int[] arr)
        //{
        //    arr = new int[5] { 1, 2, 3, 4, 5 };
        //}


        //static void giveValue2(out int[] arr)
        //{
        //    arr = new int[5] { 6, 7, 8, 9, 10 };
        //}
        //static void Main()
        //{
        //    int[] Arrys ={ 5, 4, 3, 2, 1 };
        //    int[] Arrys2;
        //    giveValue(ref Arrys);
        //    giveValue2(out Arrys2);//此处的名字不能改为 giveValue(out Arrys2),不能定义仅在ref与out上有差别的重载方法,如果是giveValue(ref Arrys)与giveValue(Arrys)之类的可以定义
        //    Console.WriteLine("the Arrys are:");
        //    for (int i = 0; i < Arrys.Length; i++)
        //    {
        //        Console.Write(Arrys[i] + " ");
        //    }
        //    Console.WriteLine();
        //    Console.WriteLine("the Arrys2 are:");
        //    for (int i = 0; i < Arrys2.Length; i++)
        //    {
        //        Console.Write(Arrys2[i] + " ");
        //    }
        //    Console.ReadKey();
        //}
        #endregion

 

        static void giveValue(out int[] arr)
        {
            arr = new int[5] { 1, 2, 3, 4, 5 };
        }
        static void giveValue(int[] arr)
        {
            arr = new int[5] { 1, 2, 3, 4, 5 };
        }

        //static void giveValue2(out int[] arr)
        //{
        //    arr = new int[5] { 6, 7, 8, 9, 10 };
        //}
        static void Main()
        {
            int[] Arrys ={ 5, 4, 3, 2, 1 };
            int[] Arrys2 ={ 5, 4, 3, 2, 1 };
            giveValue(out Arrys);
            giveValue(Arrys2);//此处的名字不能改为 giveValue(out Arrys2),不能定义仅在ref与out上有差别的重载方法,如果是giveValue(ref Arrys)与giveValue(Arrys)之类的可以定义
            Console.WriteLine("the Arrys are:");
            for (int i = 0; i < Arrys.Length; i++)
            {
                Console.Write(Arrys[i] + " ");
            }
            Console.WriteLine();
            //Console.WriteLine("the Arrys2 are:");
            //for (int i = 0; i < Arrys2.Length; i++)
            //{
            //    Console.Write(Arrys2[i] + " ");
            //}
            Console.ReadKey();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值