由堆栈所能想到的??
提到堆栈区别,大部分首先想到的是,“值类型存储在栈中,引用类型存储在堆中,引用类型在栈上存储指向堆的地址”这句话。说这个我先想说一下值类型和引用类型,以及值传递和引用传递,关于值类型有哪些,以及引用类型有哪些,这些可以自己去了解。
将一个值类型赋值给另一个值类型,是将值得本身全部赋值过去,简言之,就是值类型的值传递传递的是值得本身,如下
class Program
{
//值传递&引用传递
static void Main(string[] args)
{
//值类型:int double char bool enum... 存储值的
//引用类型:string 数组 自定义类,集合 object.. 存储对值的引用的(可以理解为存储值在堆中的数据地址)
//这里有篇博客说的很好:http://www.cnblogs.com/jiajiayuan/archive/2011/09/23/2185966.html
unsafe
{
//值传递
int n1 = 10;//地址:0x058***98
int n2 = 20;//地址:0x058***94
n1 = n2;
int* adress_n1 = &n1;//使用C#指针需要将语句块标记为unsafe表示不安全上下文
int* adress_n2 = &n2;
Console.WriteLine(n1);
Console.WriteLine(n2);
Console.WriteLine((int)adress_n1);//输出n1在栈上的地址
Console.WriteLine((int)adress_n2);//输出n2在堆栈上面的地址
Console.ReadKey();
}
}
}
值传递编辑图示
flag:这里待会将会和ref关键字有联系。
下面可以看看引用类型的引用传递又是怎么一回事。
//引用传递
static void Main(string[] args)
{
Person p1 = new Person();
p1.Name = "pc";
Person p2 = new Person();
p2.Name = "ppcc";
p2 = p1;
Console.WriteLine(p1.Name);
Console.WriteLine(p2.Name);
Console.ReadLine();
}
}
public class Person
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
引用传递编辑图示
我们知道字符串也是引用类型,但是对于字符串由于字符串拥有不可变性,所以很特殊。
static void Main(string[] args)
{
string s1 = "pc";//字符串引用类型,但是字符串拥有不可变性
string s2 = s1;
s2 = "ppcc";
Console.WriteLine(s1);
Console.WriteLine(s2);
Console.ReadLine();
//输出结果
//pc
//ppcc
}
ref参数
static void Main(string[] args)
{
int a = 20;
Test1(a);
Console.WriteLine(a);//输出是多少?是20
Console.ReadLine();
}
public static void Test1(int a1)
{
a1 += 1;
}
在Test1里面a的值是21,但是这个方法由于没有返回值,所以,最后输出结果还是原值。那这个例子和ref参数就有关了,有资料说,ref参数可以将值类型的传递改成传递地址,通过对地址的操作改变值类型本身。
static void Main(string[] args)
{
int a = 20;
Test1(ref a);
Console.WriteLine(a);//输出是多少?是21
Console.ReadLine();
}
public static void Test1(ref int a1)
{
a1 += 1;
}
关于它和out参数的区别,记住一句话,因为ref参数是从外部传递到函数里面的,所以要求必须在函数外部进行赋值,而out参数因为是从方法内部传递出去的,所以要求在方法内部必须对其进行有值操作。
out参数
static void Main(string[] args)
{
int a = 20;
int b;//使用out参数的时候 这里不用赋值,因为值是从一个函数里面传递出来的
//Test1(ref a);
Test2(out b);
Console.WriteLine(b);//输出是多少?是-1
Console.ReadLine();
}
//public static void Test1(ref int a1)
//{
// a1 += 1;
//}
public static void Test2(out int b)
{
b = 3;//在函数内部必须赋值
b -= 1;
}
留下的思考就是,out参数是否也是通过改变参数的传递方式?链接一个为什么C#中属性不可以使用ref,out参数
http://book.51cto.com/art/200910/158498.htm