1 定义和使用函数
函数定义由一下几个部分组成
- 两个关键字:static 和 void
- 函数后跟圆括号,如write()
- 一个要执行的代码块,放在花括号中
函数的定义包括函数名、返回类型以及一个参数列表,这个参数列表指定了该函数需要的参数数量和参数类型。
class progarm { static void Write() { WriteLine("Text output from function"); } static void Main(string [] args) { Write(); ReadKey(); } }
PS:一般采用PascalCase形式编写函数名
1)返回值:当函数返回一个值时,可以采用两种方式来修改函数。
在函数中指明返回的类型,但不使用关键字void。
使用return 关键字结束函数的执行,把返回值传送给调用代码。
C#6 新特性 表达式方法体
以前的函数
static double Multiply(double myVall, double myVall2)
{
return myVall * myVall2;
}
now 可以用Lambda箭头编写
static double Multiply(double myVall, double myVall2)=> myVall * myVall2;
2)参数:当函数接受参数,必须制定以下内容。
- 函数在其定义中指定接受的参数列表,以及这些类型的参数。
- 在每个函数调用中提供匹配的实参列表。
PS:形参(parameter)就是没有赋值的变量,实参(argument)就是赋值的变量。
void add(int a ,int b) ; 这里面的a,b就是形参
add(1,2); 这就是实参
①参数匹配:在调用函数时,必须使提供的参数与函数定义指定的参数完全匹配。类型、个数、顺序。
②参数数组:C#允许为函数指定一个(只能指定一个)特殊参数,这个参数必须是函数定义中的最后一个参数,称为参数数组。
参数数组允许使用个数不定的参数调用函数,可使用params关键字来定义它们。
1 static <returnType> <FunctionName>{<plType> <plName>,.... 2 params <type> [] <name> } 3 { 4 ... 5 return <returnValue>; 6 7 } 8 9 class Progarm 10 { 11 static void SumVals(params int [] vals) 12 { 13 int sum = 0; 14 foreach(int val in vals) 15 { 16 sum+=val; 17 } 18 return sum; 19 } 20 static void Main(string [] args) 21 { 22 int sum =SumVals(1,5,2,9,8); 23 WriteLine($"Summed Values ={sum}"); 24 ReadKey(); 25 } 26 } 27 28
③引用参数和值参数:
值参数:使用参数时,把一个值传递给函数使用的一个变量。在函数中对此变量的任何修改都不影响函数调用中指定的函数。
For ex:
static void ShowDouble(int val)
{
val * =2 ;
WriteLine($" val double = {0}",val);
}
int myNumber = 5;
WriteLine($"myNumber = {myNumber}");
ShowDouble(myNumber );
WriteLine($"myNumber = {myNumber}");
第一次得出的值是5,第二次是10,第三次还是5。
所以说bamyNumber作为一个参数,调用ShowDouble()并不影响Main()中的myNumber的值,即使把myNumber赋值给val后将val加倍,myNumber的值也不会变。
那么如何能够改变参数的值呢?
ref
static void ShowDouble(ref int val) { val * =2; WriteLine($"val double ={val} "); } int myNumber = 5; WriteLine($"myNumber={myNumber}",); ShowDouble(ref myNumber); WriteLine($"myNumber={myNumber}");
第一次结果是 5,第二次是10,第三次还是10。
所以ref能改变参数的值。But 使用ref 有两个限制,不能使用常量const。还有不能使用初始化后的变量,C#不允许假定ref参数在它的函数中初始化。
④输出函数:out 与ref参数的用法基本一致。但是两者还是有区别的。
把未赋值的变量用作ref参数是非法的,但是可以把未赋值的变量用作out参数。
在使用out参数时,必须把它看成尚未赋值。
static int MaxValue(int [] int Array, out int maxIndex) { int maxVal =intArray[0]; maxIndex = 0; for(int i =1; i<intArray.Length; i ++) { if(intArray[i]>maVal) { maxVal=intArray[i]; maxIndex= i ; } } return maxVal; }
必须在函数调用时使用out关键字。
2 变量的作用域
1)其他结构中变量的作用域
2)参数和返回值与全局数据
3 Main()函数
4 结构函数
1 struct CustomerName 2 { 3 public string firstName , lastName; 4 } 5 CustomerName myCustomer; 6 myCustomer.firstName = "Smith"; 7 myCustomer.lastName ="Bob"; 8 WriteLine($"{myCustomer.firstName} {myCustomer.lastName}"); 9 10 struct CustomerName 11 { 12 public string firstName , lastName; 13 public string Name() => firstName +""+lastName; 14 } 15 CustomerName myCustomer; 16 myCustomer.firstName = "Smith"; 17 myCustomer.lastName ="Bob"; 18 WriteLine(myCustomer.Name);
5 函数的重载
在调用函数时,必须匹配函数的签名。需要有不同的函数操作不同类型的变量。
函数重载允许创建多个同名函数,每个函数可使用不同的函数类型。
1 static int MaxValue(int [] intArray) 2 { 3 ... 4 return maxVal; 5 } 6 这个函数只能处理int数组。 7 8 static double MaxValue(double [] doubleArray) 9 { 10 ... 11 return maxVal; 12 } 13 这里使用了double值,函数名称是一样的。但是签名不同。 14 15 static void ShowDouble(ref int val) 16 { 17 18 } 19 static void ShowDouble(int val) 20 { 21 22 } 23 选用函数参数调用用是否包含ref关键字来确定。 24 ShowDouble(ref val); 25 ShowDouble(val);
6 委托
1 class Program 2 { 3 delegate double ProcessDelegate(double param1,double param2); 4 static double Multiply(double param1, double param2) => param1 * param2; 5 static double Divide(double param1, double param2) => param1 / param2; 6 7 8 static void Main(string[] args) 9 { 10 ProcessDelegate process; 11 WriteLine("Enter 2 numbers separated with a comma"); 12 string input = ReadLine(); 13 int commaPos = input.IndexOf(','); 14 double param1 = ToDouble(input.Substring(0,commaPos)); 15 double param2 = ToDouble(input.Substring(commaPos+1, input.Length - commaPos - 1)); 16 WriteLine("Enter M to multiply or D to divide"); 17 input = ReadLine(); 18 if (input == "M") 19 { 20 process = new ProcessDelegate(Multiply); 21 } 22 else 23 { 24 process = new ProcessDelegate(Divide); 25 } 26 WriteLine($"Result:{process(param1,param2)}"); 27 ReadKey(); 28 } 29 30 }
7 总结