堆空间和栈空间
栈
1.系统分配内存,自动回收内存
2.空间比堆空间小
3.存取速度比堆空间快
4.数据的存储,先进后出
堆
1.手动申请与释放内存
2.空间比栈空间大
3.存取速度比栈空间慢
值类型和引用类型
值类型和引用类型
值类型:定义的变量时存储在栈中的,如:int float char bool struct enum
引用类型:定义的变量,具体的值存在堆中,指向堆中数据的地址存在栈中,如:string 数组
值传递和引用传递
值传递:发生在值类型互相赋值之间,传递的是具体的值
引用传递:发生在引用类型相互赋值之间,传递的是地址
int a = 10; int b = a;//值传递 a = 20; Console.WriteLine(b); //10 不受a变化影响 int[] array1 = { 1, 2, 3 }; int[] array2 = array1;//引用传递 array1[2] = 10; Console.WriteLine(array2[2]); //10 赋值的只是同一个物理地址,所以值会变
函数(方法)
概念
将一堆代码进行封装重用的一种机制,函数本质上是一块具有名称的代码块
定义
//没有返回值 没有参数的方法 static void Test1() { Console.WriteLine("hello world"); } //没有返回值 有参数(有类型) static void Test2(int num)//形参 { Console.WriteLine(num); } void Test3(int num, string str) { //没有返回值的方法也可以使用return if (num>10) { return; } Console.WriteLine(); } //有返回值 没有参数 static int Test4() { return 1;//返回一个值 Console.WriteLine("Test4"); } //有返回值 还有参数 static string Test5(string str) { if (str == "A") { return "a"; while (true) { return "b"; } } else { return "b"; } }
调用
//调用函数 在函数中调用函数 通过函数名调用 Test1(); //如果在stutic的Main函数内直接调用的只能是stutic的函数 //Player player; //player.playerTest1(); //有参数的函数调用 int num = 10; int a = 20; Test2(a-num);//实参 参数类型要匹配 //有返回值 int a4=Test4();//返回值不是必须接受 Console.WriteLine(a4); Console.ReadKey();
形参
形式参数就是方法定义时参数列表中的参数,无实际的值
实参
实际参数是调用方法时,填入参数列表的参数,有实际的值
Return
1.结束方法的执行。
2.返回方法需要的返回值
3.方法内代码执行到任意一个return,都将结束方法的执行
4.如果方法有返回值,那么要保证任意情况下必须有一个return返回返回值
5.没有返回值的方法中也可以使用return,代表直接退出函数的作用,不需要返回具体的值
练习
struct RoundNum { public float area; public float pre; } struct ArrCount { public int max; public int min; public int sum; public float avg; } static int MaxNum(int num1, int num2) //返回最大值 { return num1 > num2 ? num1 : num2; } static RoundNum AreaPre(int r) //求圆面积和周长 { const float PI = 3.1415926f; RoundNum roundNum; roundNum.area = PI * r * r; roundNum.pre = 2 * PI * r; return roundNum; } static ArrCount SumMax(int[] arr) //计算数组总和 最大值 最小值和平均值 { ArrCount array; array.max = arr[0]; array.min = arr[0]; array.sum = 0; for (int i = 0; i < arr.Length; i++) { if(array.max< arr[i]) { array.max = arr[i]; } if(array.min> arr[i]) { array.min = arr[i]; } array.sum += arr[i]; } array.avg = (float)array.sum/ arr.Length; return array; } static string Score(int num) //求成绩 { string score = ""; num = num / 10; switch(num) { case 10: case 9: score = "优"; break; case 8: score = "良"; break; case 7: score = "中"; break; case 6: score = "差"; break; case 5: case 4: case 3: case 2: case 1: case 0: score = "不及格"; break; default: score = "无效"; break; } return score; } static void Main(string[] args) { int a = 10; int b = 20; int max_ = MaxNum(a, b); //调用求最大值的函数,并给函数传两个实参 a,b 用max_接收函数返回的值 Console.WriteLine("最大值是:{0}",max_); int r = 5; //定义半径r RoundNum roundNum= AreaPre(r); //调用求圆面积和周长的函数,并给函数传一个实参r 用结构体roundNum接收函数返回的值 Console.WriteLine("圆的面积是:{0},周长是:{1}",roundNum.area,roundNum.pre); int[] arr = { 21, 32, 12, 34, 11 }; ArrCount array = SumMax(arr); //调用计算数组的函数,并给函数传一个实参 数组arr 用结构体array接收函数返回的值 Console.WriteLine("总和:{0},最大值:{1},最小值:{2},平均值:{3}",array.sum,array.max,array.min,array.avg); Console.WriteLine("请输入你的成绩(满分100)"); int score = int.Parse(Console.ReadLine()); string scoreStr = Score(score); //调用求成绩的函数 传实参score 并用scoreStr接收函数返回的值 Console.WriteLine(scoreStr); Console.ReadKey(); }
out和ref
当我们在定义一个参数的时候,可以使用out或ref修饰
值参数:复制实参的内容传递的方法
引用参数:复制实参的地址传递到引用方法
ref 引用参数
1.方法定义时,形参列表里参数添加ref关键字的参数为引用参数
2.调用方法时,引用参数必须在传递的实参前加ref关键字
3.变量如果使用ref进行传參,必须先赋值。
4.作用
1.引用参数传递的是指向实参里存储内容的地址
2.方法内可以影响实参里的存储
out输出参数
1.方法定义时,形参列表里参数前加out关键的参数为输出参数
2.调用方法时,引用参数必须在传递的实参前加out关键字
3.被out修饰的参数在函数内部是需要被赋值的
4.可以使用数组或结构体返回多个数据,也可以使用基本数据类型返回单一数据
5.作用
1.输出参数传递的是指向实参里存储内容的地址
2.方法内必须对输出参数赋值
3.方法需要传递出多个数据时使用
4.可以使用数组或结构体返回多个数据,也可以使用基本数据类型返回单一数据