C#笔记14 方法01

C#笔记14 方法01

——本系列是基于人民邮电出版社《C#2008 C#图解教程》、清华大学出版社《C#入门经典(第五版)》两本书的自学C#笔记,如果您发现了本文的纰漏,还望不吝指正。

写在前边

在 C#笔记10 类:基础 中,我们已经知道,方法是类中重要的一个函数成员

除了类中,方法也可以声明在结构体,接口中

*复习:方法是具有名称的可执行代码块,当方法被调用时,它执行自己所含的代码,然后返回到调用它的代码。有些方法返回一个值到它们被调用的位置。

1. 方法的结构

在类的相关笔记中,我们已经知道了如何声明一个简单的方法,

  • 返回类型
  • 名称
  • 参数列表
  • 方法体

还是上次的例子:

class SimpleClass
{
	void PrintNum()		//没有返回值,参数列表为空
	{
		ConsoleWriteLine("1");	//{}内为方法体
	}
}

我们把方法分成有两个主要部分:方法头和方法体

  • 方法头:方法名,是否返回数据,返回什么类型的数据,什么类型的输入可以传入方法
  • 方法体:{ }内可执行代码的语句序列

2. 本地变量和本地常量

本地变量和字段一样,用来保存数据,但是本地变量的影响范围仅限于当前方法块
本地常量和本地变量一样,影响范围仅限于当前方法块
关于常量,参考 C#笔记11 类:类成员补充01中的成员常量
C#笔记14 方法01_第1张图片
——上图出自 人民邮电出版社《C#2008 C#图解教程》第5章

3. 方法调用

使用方法名调用方法

例:以下代码展示了在同一类中创造出类的实例,调用其他方法,实际上即使是不同类中的调用方法是相同的

	class NumberManipulator
   {
      public int FindMax(int num1, int num2)
      {
         /* 局部变量声明 */
         int result;

         if (num1 > num2)
            result = num1;
         else
            result = num2;

         return result;
      }
      static void Main(string[] args)
      {
         /* 局部变量定义 */
         int a = 100;
         int b = 200;
         int ret;
         NumberManipulator n = new NumberManipulator();

         //调用 FindMax 方法
         ret = n.FindMax(a, b);
         Console.WriteLine("最大值是: {0}", ret );
         Console.ReadLine();
      }
   }
   //代码来自 菜鸟教程 https://www.runoob.com/csharp/csharp-methods.html

控制台输出结果:


最大值是: 200


*静态方法的调用方法,同静类的外部访问静态成员,使用点(.)运算符,类名.成员名

4. 返回值

方法可以向调用代码返回一个值。返回的值被插入到调用代码中发起调用的表达式所在的位置

4.1 需要返回值

必须在方法名前声明返回类型

例:下边代码中,GetHour()方法前的int,代表了这个方法,会返回int类型

int GetHour()
{
    DateTime dt = DateTime:Now;        // 获取当前日期和时间
    int hour = dt.Hour;      // 获取小时数
    return hour; 		//返回一个int
}

例:返回的类型也可以是用户定义的类型

MyClass method3()
{
    MyClass mc = new MyClass();
    return mc;                            // 返回一个Myclass对象
}

关键字return:

  • 声明了返回类型的方法必须使用返回语句从方法中返回一个值;
  • 返回语句包括关键字return及其后面的表达式。每一条穿过方法的路径都必须以一条这种形式的return语句结束。

4.2 不需要返回值

必须在方法名前声明返回类型为void

void方法:

  • void方法不需要返回语句;
  • 当控制流到达方法体的关闭大括号时,控制返回到调用代码,并且没有值被插入到调用代码中;
  • 可以在任何时候使用return返回语句退出方法,不带参数。

例:

void SomeMethod()
{
    if(SomeCondition)
    return;
}

5. 参数

就是方法头中圆括号里的内容,没有内容的话就是无参方法

5.1 形参

声明在方法的参数列表中,而不是方法体中的本地变量

  • 因为形参是变量,所以它们有类型和名称,并能被写入和读出
  • 参数列表中可以有任意数目的形参声明,并且声明间用逗号隔开

上边的例子中,方法 FindMax中,圆括号中的"num1, num2",就是两个int类型的形参

public int FindMax(int num1, int num2) { }

5.2 实参

方法被调用时,用于初始化形参的表达式或变量,实参放在方法调用的参数列表中

  • 实参的数目必须和形参的数目相同
  • 每个参数必须和相应形参的类型匹配

还是上边的例子中,调用 FindMax 方法时,ret = n.FindMax(a, b),圆括号中的"a,b",就是两个int类型的实参

int a = 100;
int b = 200;
int ret;
NumberManipulator n = new NumberManipulator();

//调用 FindMax 方法
ret = n.FindMax(a, b);

5.3 三种向方法传递参数的方式

1).值参数(参数传递的默认方式)

数据通过复制实参的值到形参的方式传递到函数

实参和形参使用的是两个不同内存中的值(因为系统在栈中为形参单独分配了内存)。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。

例:下面的代码中,把myNumber作为一个参数,调用ShowDouble()并不影响myNumber的值,即使赋予val的参数被加倍,myNumber的值也不变。

static void ShowDouble(int val)
{
    val *= 2;
    Console.WriteLine("val doubled = {0}", val);
}
    //参数val在这个函数中被加倍,如果按以下方式调用它:
    int myNumber = 5;
    Console.WriteLine("myNumber = {0}", myNumber);
    ShowDouble(myNumber);
    Console.WriteLine("myNumber = {0}", myNumber);

控制台输出结果:


myNumber = 5
val doubled = 10
myNumber = 5


2).引用参数 ref

即方法处理的变量与方法调用中使用的变量相同,而不仅仅是值相同的变量(因为系统不会为形参单独分配内存,而是直接引用实参的内存位置)。因此,对这个变量进行的任何改变都会影响用作参数的变量值。

例:还是上边的代码,在方法的参数列表中,加入ref关键字,使用引用参数。这次,myNumber的值就被ShowDouble()修改了。

static void ShowDouble(ref int val)
{
    val *= 2;
    Console.WriteLine("val doubled = {0}", val);
}
    //添加ref关键字后的调用:
    int myNumber = 5;
    Console.WriteLine("myNumber = {0}", myNumber);
    ShowDouble(ref myNumber);	//传参时也必须有ref
    Console.WriteLine("myNumber = {0}", myNumber);

控制台输出结果:


myNumber = 5
val doubled = 10
myNumber = 10


3).输出参数 out

通过参数列表可以额外输出一个信息(return 语句可用于只从函数中返回一个值。可以使用输出参数来从函数中返回两个值)

在方法使用out参数时,out参数必须看作是还未赋值

在被读取之前,方法返回之前,必须被赋值

例:下面的代码中,方法MaxValue返回一个int值(return maxVal),在参数列表中加入一个out int maxIndex,让方法额外输出一个int值(maxIndex)

static int MaxValue(int[] intArray, out int maxIndex)
{
    int maxVal = intArray[0];
    maxIndex = 0;
    for (int i = 1; i < intArray.Length; i++)
    {
        if (intArray[i] > maxVal)
        {
            maxVal = intArray[i];
            maxIndex = i;		//函数返回之前,maxIndex被赋值
        }
    }
    return maxVal;
}
    //可以采用以下方式使用该函数:
    int[] myArray = { 1, 8, 3, 6, 2, 5, 9, 3, 0, 2 };
    int maxIndex;
    //使用out参数时,out参数还未赋值
    Console.WriteLine("The maximum value in myArray is {0}", MaxValue(myArray, out maxIndex));
	Console.WriteLine("The first occurrence of this value is at element {0}",maxIndex + 1);

控制台输出结果:


The maximum value in myArray is 9
The first occurrence of this value is at element 7


写在最后

参数数组 params

上边所有的参数类型,都必须严格遵守一个实参对应一个形参,而参数数组则允许零个或者多个实参对应到这个特殊的形参。

1. params:可变参数传参

1).在函数定义时,在数据类型前加上
2).params修饰的参数必须是数组类型
3).必须放在方法参数列表的最后一位,并且只能有一个参数数组

例:如下方法头中,形参intVals可以代表零个或多个int实参

void ListInts( params int[] intVals) { }

2. 调用参数数组所在方法

  • 逗号分隔的数组元素直接作为实参
ListInts( 10, 20 , 30 );
  • 定义好同类型的数组再作为实参调用
int[] intArray = { 1, 2, 3 };
ListInts( intArray );

例:下面的代码延续上边例子中定义的方法

class MyClass
{
    public void ListInts(params int[] intVals)
    {
        if ((intVals != null) && (intVals.Length != 0))
        {
            for (int i = 0; i < intVals.Length; i++)
            {
                intVals[i] = intVals[i] * 10;
                Console.WriteLine(intVals[i]);
            }
        }    
    }
}
class Program
{
	static void Main()
	{
		int a = 5, b = 6, c = 7;
		Console.WriteLine("{0},{1},{2}", a, b, c);
		
		MyClass mc = new MyClass();
		mc.ListInts(a, b, c);
		
		Console.WriteLine("————分割线————");
		int[] intArray = { 1, 2, 3 };
		Console.WriteLine("{0},{1},{2}", intArray[0], intArray[1], intArray[2]);
		mc.ListInts(intArray);	
	}
}

控制台输出结果:


5,6,7
50
60
70
————分割线————
1,2,3
10
20
30


参数类型总结

C#笔记14 方法01_第2张图片
——上图出自 人民邮电出版社《C#2008 C#图解教程》第5章

你可能感兴趣的:(C#笔记基础篇,c#)