您的位置:首页 > 编程语言 > C#

C# ----- 数据类型(params/ref/out)

2015-12-08 16:17 579 查看
这篇是各种数据类型,各种参数总结。有点乱。没来得及整理。有空会再整理下。还有这是搜集的各路资料和自己的一些总结。谢谢各路大神!!
1.理论概念

C#数据类型结构图:



计算机分为5个区

1.常量区
2.静态区 (static修饰的)
3.代码区 运行方法的时候会找到代码区
4.栈区(值类型,定义一个变量入栈开辟空间,定义完自动释放空间)int a = 10,此处a为值
5.堆区(数组中,new称为运算符,new的时候在堆中开辟空间)int[] a = new int[];此处a为存储的地址

拷贝
值类型是先copy相同的数值,再赋值给新的变量
引用类型是把存储的地址赋值给新的变量(数组)

2.示例
(1)值类型转换引用类型

class MainClass
{
public void Jiaohuan(int x,int y)
{
x=x+y;
y=x-y;
x=x-y;
}
MainClass mainclass = new MainClass();
int a = 12;
int b = 35;
mainclass.Jiaohuan(a,b);
Console.WriteLine ("a={0},b={1}",a,b);//然而实参没有交换
int c =30;
int d = c;
d = 40;
Console.WriteLine ("c={0},d={1}",c,d);


输出不改变

若想改变则在方法里面形参前加ref,输出处实参前也加ref;(ref意为把值类型转换为引用类型)
//形参的值发生改变后,实参的值也会发生改变
如下:

class MainClass
{
public void Jiaohuan( ref int x,ref int y)//ref只适用于值类型,相当于把值类型转化为引用类型
{
x=x+y;
y=x-y;
x=x-y;
}
public static void Main (string[] args)
{
MainClass mainclass = new MainClass();
int a = 12;
int b = 35;
mainclass.Jiaohuan(ref a,ref b);
Console.WriteLine ("a={0},b={1}",a,b); //形参的值发生改变后,实参的值也会发生改变


(2)数组是引用类型,则输出会改变

public void Maopao(int[]a)
{
for(int i = 0;i<a.Length-1;i++){
for(int j =0;j<a.Length-i-1;j++){
if(a[j]>a[j+1])
{
int temp = a[j+1];
a[j+1] = a[j];
a[j] = temp;
}
}
}
int[] s = {1,5,6,7,2,4,3};
int[] h = s;
h[1] = 10;
Console.WriteLine (s[1]);
mainclass.Maopao(s);


输出改变

~!!注意:类里的字段存放在堆区(即使字段中用的变量是值类型)

3.装箱,拆箱
装箱:把值类型的数据转换成引用类型的数据的过程

int  num = 23;
object obj = num;
Console.WriteLine (obj);


拆箱:把引用类型的数据转换成值类型的数据称为拆箱

int count = (int)obj;
Console.WriteLine (count);


示例:
①params表示可变数组,即不确定数组的长短情况下声明。且params关键字后不允许有其他参数。

public void PrintArr( params int[] a)//可变数组参数params
{
foreach(int n in a)
{
Console.Write (n+" ");
}
}

//输出数组
int[] sh = {12,54,45,32,45};
mainclass.PrintArr(sh);
Console.WriteLine ();
mainclass.PrintArr(2,5,7,8,4,9);//使用params后可省去定义数组
Console.WriteLine ();
mainclass.PrintArr();


②若params与其他值类型同时存在,则默认值类型后为可变数组

public void PrintArr(int a,int b,params int[] jk)//可变数组参数params与别的值类型同存在
{
foreach(int y in jk)
{
Console.Write (y+" ");
}
}
mainclass.PrintArr(2,5,7,8,4,9);//使用params后可省去定义数组


输出结果:7 8 4 9

C# 参考之方法参数关键字:params、ref及out
如果在为方法声明参数时未使用 ref 或 out,则该参数可以具有关联的值。
可以在方法中更改该值,但当控制传递回调用过程时,不会保留更改的值。
通过使用方法参数关键字,可以更改这种行为。

4.ref
上面在值类型和引用类型的示例介绍中有提到了ref的用法。
ref 关键字使参数按引用传递。
其效果是,当控制权传递回调用方法时,在方法中对参数所做的任何更改都将反映在该变量中。

若要使用 ref 参数,则方法定义和调用方法都必须显式使用 ref 关键字。
传递到 ref 参数的参数必须最先初始化。这与 out 不同,out 的参数在传递之前不需要显式初始化。
属性不是变量,因此不能作为 ref 参数传递。
尽管 ref 和 out 在运行时的处理方式不同,但它们在编译时的处理方式是相同的。因此,如果一个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。例如,从编译的角度来看,以下代码中的两个方法是完全相同的。如果尝试这么做,将导致不能编译该代码。
如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行重载。

示例:

// keywords_ref.cs

using System;

class App
{
public static void UseRef(ref int i)
{
i += 100;
Console.WriteLine("i = {0}", i);
}

static void Main()
{
int i = 10;

// 查看调用方法之前的值
Console.WriteLine("Before the method calling: i = {0}", i);

UseRef(ref i);

// 查看调用方法之后的值
Console.WriteLine("After the method calling: i = {0}", i);
Console.Read();
}
}


控制台输出:
Before the method calling : i = 10
i = 110
After the method calling: i = 110

5.out

out 关键字会导致参数通过引用来传递。这与 ref 关键字类似。
与 ref 的不同之处:
ref 要求变量必须在传递之前进行初始化。
尽管作为 out 参数传递的变量不需要在传递之前进行初始化,但需要调用方法以便在方法返回之前赋值。

//买烟的方法  +out
public int Maiyan(int money,out int change)//把零钱输出来,有out的话是把形参赋值给实参
{
int num = money/20;
change = money%20;
return num;
}

//输出参数,当返回值为两个,则在方法定义参数处加out,
int lingqian;
int number = mainclass.Maiyan(50,out lingqian);//拿了多少钱
Console.WriteLine (number);
Console.WriteLine (lingqian);


与 ref 示例不同的地方只要将 ref 改为 out,然后变量 i 仅需要声明即可。

static void Main()
{
//int i = 10; 改为
int i;
//
}


6.参数 params
params 关键字可以指定在参数数目可变处采用参数的方法参数。
在方法声明中的 params 关键字之后不允许任何其他参数,并且在方法声明中只允许一个 params 关键字。

数组参数总结params

1.参数的长度可变。长度可以为0。

2.只能使用一次,而且要放到最后。

3.后跟数组类型,不能跟ref、out一起搭配使用

C#中方法的参数有4中类型:
值参数:不附加任何修饰符。
输出参数:以out修饰符声明,可返回一 个或多个值给调用者。
引用参数:以ref修饰符声明。
数组参数:以params修饰符声明。

示例:

// keywords_params.cs

using System;

class App
{
public static void UseParams(params object[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.WriteLine(list[i]);
}
}

static void Main()
{
// 一般做法是先构造一个对象数组,然后将此数组作为方法的参数
object[] arr = new object[3] { 100, 'a', "keywords" };
UseParams(arr);

// 而使用了params修饰方法参数后,我们可以直接使用一组对象作为参数
// 当然这组参数需要符合调用的方法对参数的要求
UseParams(100, 'a', "keywords");

Console.Read();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: