Stack(栈)
所有值类型和引用类型的引用都存储在栈上
值类型赋值原理:在栈上复制的真实值
Heap(堆)
堆上存储的真实对象本身真实对象的属性
1.值类型和引用类型
值类型源于System.ValueType家族,每个值类型的对象都有一个独立的内存区域用于保存自己的值,值类型数据所在的内存区域成为栈.
值类型主要包括基本数据类型和枚举类型
值类型的赋值原理:
在栈上复制的真实值
实例代码:
//张浩和李明去年身高都是170cm,今年李明长到了180cm,张浩没有变化, //输出去年和今年两人身高 int zhheight = 170; int lmheigt = zhheight; Console.WriteLine("去年张浩身高是{0} 李明的身高是{1}", zhheight, lmheigt); lmheigt = 180; Console.WriteLine("今年张浩身高是{0} 李明的身高是{1}", zhheight, lmheigt);
2.引用类型
命名空间:System.Onject
引用类型主要包括数组,类和接口,字符串等
储存在栈和堆中
堆上储存的真实对象本身真实对象的属性
示例代码:
int[] zhArray={170,60}; int[] lmArray = zhArray; Console.WriteLine("去年张浩身高是{0},体重是{1} 李明的身高是{2},体重是{3}", zhArray[0],zhArray[1], lmArray[0],lmArray[1]); Console.WriteLine("================我是高贵的分割线===================="); lmArray[0] = 180; lmArray[1] = 70; Console.WriteLine("今年张浩身高是{0},体重是{1} 李明的身高是{2},体重是{3}", zhArray[0], zhArray[1], lmArray[0], lmArray[1]);
//解决: int[] zhArray = { 170, 60 }; int[] lmArray = new int[2]; for (int i = 0; i < zhArray.Length; i++) { lmArray[i] = zhArray[i]; } Console.WriteLine("去年张浩身高是{0},体重是{1} 李明的身高是{2},体重是{3}", zhArray[0], zhArray[1], lmArray[0], lmArray[1]); Console.WriteLine("================我是高贵的分割线======================"); lmArray[0] = 180; lmArray[1] = 70; Console.WriteLine("今年张浩身高是{0},体重是{1} 李明的身高是{2},体重是{3}", zhArray[0], zhArray[1], lmArray[0], lmArray[1]);
3.细分值类型和引用类型
二.结构
1.定义:
语法:
访问修饰符 struct 结构名 { //结构体 }
特点:
结构中可以有字段,也可以有方法
定义时,结构中的字段不能被赋初值
示例代码:
//定一个自己的结构体 public struct MyPointer { //成员 属性 结构体的成员变量不能有初值 private int age; public int Age { get { return age; } set { age = value; } } //结构体中可以定义方法 public void show() { } }
2.使用
可以不用new。直接定义结构的对象即可
声明结构的对象后,必须给结构的成员赋初值
示例代码:
static void Main(string[] args) { //使用结构体 MyPointer pointer=new MyPointer(); pointer.Age = 20; pointer.show(); }
3.使用经验
不推荐使用(结构用得越多所消耗的存储空间也越多)
4.构造函数
示例代码:
public class Player { //无参 private Player() { //归类:方法(方法)/函数 (面向过程) } //有参 public Player(string name) { //归类:方法(方法)/函数 (面向过程) } }
5.装箱和拆箱
将值类型转换为引用类型的过程称为装箱,反之称为拆箱
实际开发尽量避免 装/拆 箱
原因:
装/拆 箱都会降低程序性能
示例代码:
static void Main(string[] args) { int num = 1; object obj = num; //有装箱操作 int result = (int)obj; //拆箱操作 //要想拆箱,先有装箱。 }
二.不同类型的参数传递
1.值方式参数传递
1)使用值类型作为参数
以值类型作为参数进行值方式传递参数时,不能改变值类型参数的值
int num1 = 3; int num2 = 5; Console.WriteLine("交换前:num1的值{0} num2的值{1}", num1, num2); //最简单的两个变量交换 //借助第三方 Change(num1, num2); Console.WriteLine("交换后:num1的值{0} num2的值{1}", num1, num2); static void Change( int num1, int num2) { int temp = num1; num1 = num2; num2 = temp; }
2)使用引用类型作为参数
以引用类型作为参数进行值方式传递参数时,能改变引用类型参数的值
static void Main(string[] args) { Voter voter = new Voter(); SE se = new SE(); se.popularity = 10; voter.Vote(se); voter.Vote(se); Console.WriteLine(se.popularity); } public void Vote(SE se) { se.popularity++; } public class SE { public int popularity; }
2.引用方式参数传递(ref)
1.使用引用类型作为参数
以值类型作为参数进行引用方式传递参数时,能改变值类型参数的值
int num1 = 3; int num2 = 5; Console.WriteLine("交换前:num1的值{0} num2的值{1}", num1, num2); //最简单的两个变量交换 //借助第三方 Changeref num1,ref num2); Console.WriteLine("交换后:num1的值{0} num2的值{1}", num1, num2); static void Change(ref int num1,ref int num2) { int temp = num1; num1 = num2; num2 = temp; }
2.使用引用类型作为参数
以值引用型作为参数进行引用方式传递参数时,能改变引用类型参数的值