(原创)c#学习笔记06--函数01--定义和使用函数02--参数

6.1.2  参数

  当函数接受参数时,就必须指定下述内容:

    函数在其定义中指定要接受的参数列表,以及这些参数的类型。

    在每个函数调用中匹配的参数列表。

  这涉及到下述代码:

      static <returnType> <FunctionName>(<paramType> <paramName>, ...) 
      { 
          ... 
          return <returnValue>; 
      }

  其中可以有任意多个参数,每个参数都有一个类型和一个名称。参数用逗号分隔开。每个参数都在函数的代码中用作一个变量。

  例如,下面是一个简单的函数,带有两个double参数,并返回它们的乘积:

      static double Product(double param1, double param2) 
      { 
          return param1 * param2; 
      }

  下面看一个示例,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ch06Ex02
{
    class Program
    {
        static int MaxValue(int[] intArray)
        {
            int maxVal = intArray[0];
            for (int i = 1; i < intArray.Length; ++i)
            {
                if (intArray[i] > maxVal)
                {
                    maxVal = intArray[i];
                }
            }
            return maxVal;
        }

        static void Main(string[] args)
        {
            int[] myArray = { 1, 8, 3, 5, 9, 4, 45, 1, 0, 1 };
            Console.WriteLine("The maximum value in myArray is {0}", MaxValue(myArray));
            Console.ReadKey();
        }
    }
}

1. 参数匹配

  在调用函数时,必须使参数与函数定义中指定的参数完全匹配,这意味着要匹配参数的类型、个数和顺序。

  note: 使用函数的名称和参数定义函数的签名。

  

2. 参数数组

  C#允许为函数指定一个(只能指定一个)特定的参数,这个参数必须是函数定义中的最后一个参数, 称为参数数组。参数数组可以使用个数不定的参数调用函数,可以使用params关键字定义它们。

  参数数组可以简化代码,因为不必从调用代码中传递数组,而且传递同类型的几个参数,这些参数放在可在函数中使用的一个数组中。

  定义使用参数数组的函数时,需要使用下列代码:

      static <returnType> <FunctionName>(<p1Type> <p1Name>, ...,params <type>[] <name>) 
      { 
          ... 
          return <returnValue>; 
      }

  使用下面的代码可以调用该函数。

<FunctionName>(<p1>, ..., <val1>, <val2>, ...)

  其中<val1>和<val2>等都是<type>类型的值,用于初始化<name>数组。可以指定的参数个数几乎不受限制。唯一的限制是它们都必须是<type>类型。甚至可以根本不指定参数。

  这一点使参数数组特别适合于为在处理过程中要使用的函数指定其他信息。

  例如,假定有一个函数GetWord(),它的第一个参数是一个string值,并返回字符串中的第一个单词。

string firstWord = GetWord("This is a sentence."); 

  其中firstWord被赋予字符串This。

  可在GetWord()中添加一个params参数,以根据其索引选择另一个要返回的单词:

string firstWord = GetWord("This is a sentence.", 2); 

  假定第一个单词计数为1,则firstWord就被赋予字符串is。

  也可以在第3个参数中限制返回的字符个数,同样通过params参数来实现:

string firstWord = GetWord("This is a sentence.", 4, 3); 

  此时firstWord被赋予字符串sen。

  下面的示例定义并使用带有params类型参数的函数。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Ch06Ex03
{
    class Program
    {
        static int SumVals(params int[] vals)
        {
            int sum = 0;
            foreach (int val in vals)
            {
                sum += val;
            }
            return sum;
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Summed values = {0}", SumVals(1, 5, 2, 9, 8));
            Console.ReadKey();
        }
    }
}

3. 引用参数和值参数

  本章迄今定义的所有函数都带有值参数。其含义是,在使用参数时,是把一个值传递给函数使用的一个变量。对函数中此变量的任何修改都不影响函数调用中指定的参数。

  例如,下面的函数使传递过来的参数值加倍,并显示出来:

      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

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

  这很不错,但如果要改变myNumber的值,就去有问题。可以使用一个为myNumber返回新值的函数:

      static int DoubleNum(int val) 
      { 
          val *= 2; 
          return val; 
      }

      // use
      int myNumber = 5; 
      Console.WriteLine("myNumber = {0}", myNumber); 
      myNumber = DoubleNum(myNumber); 
      Console.WriteLine("myNumber = {0}", myNumber);

  但这段代码一点也不直观,且不能改变用作参数的多个变量值(因为函数只有一个返回值)。

  此时可以通过“引用”传递参数。即函数处理的变量与函数调用中使用的变量相同,而不仅仅是值相同的变量。因此,对这个变量进行的任何改变都会影响用作参数的变量值。为此,只需使用ref关键字指定参数:

      static void ShowDouble(ref int val) 
      { 
          val *= 2; 
          Console.WriteLine("val doubled = {0}", val); 
      }

      // use
      int myNumber = 5; 
      Console.WriteLine("myNumber = {0}", myNumber); 
      ShowDouble(ref myNumber); 
      Console.WriteLine("myNumber = {0}", myNumber); 

  输出:

      myNumber = 5 
      val doubled = 10 
      myNumber = 10

  这次,myNumber被ShowDouble()修改了。

  用作 ref 参数的变量有两个限制

    首先,函数可能会改变引用参数的值,所以必须在函数调用中使用“非常量”变量(即不能是const变量)。

    其次,必须使用初始化过的变量。

4 输出参数

  除了按引用传递值之外,还可以使用out关键字,指定所给的参数是一个输出参数。out关键字的使用方式与ref关键字相同(在函数定义和函数调用中用作参数的修饰符)。实际上,它的执行方式与引用参数完全一样,因为在函数执行完毕后,该参数的值将返回给函数调用中使用的变量。但是,存在一些重要区别:

    把未赋值的变量用作ref参数是非法的,但可以把未赋值的变量用作out参数。

    另外,在函数使用out参数时,out参数必须看作是还未赋值。即调用代码可以把已赋值的变量用作out参数,存储在该变量中的值会在函数执行时丢失。

  例如,考虑前面返回数组中最大值的MaxValue()函数,略微修改该函数,获取数组中最大值的元素索引。为简单起见,如果数组中有多个元素的值都是这个最大值,只提取第一个最大值的索引。为此,修改函数,添加一个out参数,如下所示:  

      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; 
              } 
          } 
          return maxVal; 
      } 

  可以采用以下方式使用该函数:

      int[] myArray = { 1, 8, 3, 6, 2, 5, 9, 3, 0, 2 }; 
      int maxIndex; 
      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 

  注意,必须在函数调用中使用out关键字,就像ref关键字一样。

  

原文地址:https://www.cnblogs.com/wodehao0808/p/4911856.html