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();
}
}
}