C#(十四)之函数(方法)

简介: 本篇内容记录了函数、函数的参数、参数匹配、递归函数。

QQ图片20220426110546.jpg

C#的函数


1:声明函数


C#的函数和php的函数功能相同,但是定义方法不同


函数状态 + 返回类型 + (参数){
       Method body:方法主体,包含了完成任务所需的指令集。
}


注意返回类型一定要与定义好的返回类型保持一致。


函数可以没有参数。


实例:


/**
* 定义一个静态函数
 */
static int hanshu(int a, int b, int c)
{
     int total = a + b + c;
     return total;
}


在主函数中调用


/* C#主要的运行函数,就是main函数 */
static void Main(string[] args)
{
     int total = hanshu(1,2,3);
     Console.WriteLine(total);  // 输出6
}


2:函数的参数


实际参数:也就是我们所说的实参。 实参是调用的时候传递的参数。 形式参数:也就是我们说的形参。 形参是函数接受的参数。


(1):值传递:按值传递,传递给函数的值发生变化,原本的值是不会发生变化的。


/**
* 定义一个静态函数
 */
static int hanshu(int a, int b, int c)// 这里边的a,b,c是形式参数
{
     int total = a + b + c;
     return total;
}
/* C#主要的运行函数,就是main函数 */
static void Main(string[] args)
{
     int total = hanshu(1, 2, 3);// 1,2.3是实际参数
      Console.WriteLine(total);  // 输出6
}


(2):地址传递:按值传递,传递给函数的值发生变化,原本的值会发生变化的。


复杂参数的地址传递


如果参数不是一个值,而是一个数组或者是一个对象,那么应用到地址传递。


/* C#主要的运行函数,就是main函数 */
        static void Main(string[] args)
        {
            //int total = hanshu(1, 2, 3);// 1,2.3是实际参数
            //Console.WriteLine(total);  // 输出6
            int[] number = { 1,2,3,4,5};
            foreach (var item in number)
            {
                Console.WriteLine("传递前:{0}",item);
                /*传递前:1
                传递前:2
                传递前:3
                传递前:4
                传递前:5*/
            }
            // 调用函数
            Message(number);
            foreach (var item in number)
            {
                 Console.WriteLine("传递后:{0}",item);
                /*传递后:1
                传递后:4
                传递后:9
                传递后:16
                传递后:25*/
            }
        }
        /**
         * 定义一个没有返回值的数组按地址传递的数组
         */
        static void Message(int[] array) {
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = array[i] * array[i];
            }
        }


引用型参数地址传递(ref):


官方关于形参和实参以及值传递与地址传递的说法是:


按值传递的时候,实参和形参处于不同内存空间,所以,值的变化不会发生关联。

按地址传递的时候,实参和形参处于相同内存空间,所以,值得变化会发生关联。

那么如果我们想按值传递的时候达到的效果与按地址传递的效果一样,我们这里就用到了引用型参数。关键字 : ref


ref 型参数使用前必须赋值。


/**
        * 定义一个静态函数(引用性参数)
        */
        static void Refs(ref int a, ref int b,ref int c)// 这里边的a,b,c是形式参数
        {
            a = a * a;
            b = b * b;
            c = c * c;
        }
/* C#主要的运行函数,就是main函数 */
        static void Main(string[] args)
        {
            int aa = 2;
            int bb = 3;
            int cc = 4;
            Refs(ref aa, ref bb, ref cc);
            Console.WriteLine(aa); // 4
            Console.WriteLine(bb); // 9
1.   Console.WriteLine(cc); // 16
        }


输出型参数地址传递(out):


其用法与引用性参数大致一样,只有一个区别:

ref 关键字指定的参数必须是“变量”,且必须赋值。

Out型参数引入前不需赋值,赋值也没用。


/**
         * 定义一个静态函数(输出型参数)
         */
        static void Mess(int aa,out int bb)
        {
            int cc = aa;
            bb = aa;
            aa = 2 * cc;
        }
/* C#主要的运行函数,就是main函数 */
        static void Main(string[] args)
        {
            int aaa = 52;
            int bbb;
            Mess(aaa,out bbb);
            Console.WriteLine(aaa); //52
            Console.WriteLine(bbb); //52
            // 在函数中将aaa的值附给了输出型参数bb,实参bbb与形参bb在同一内存中,所以值得改变会关联
            // aaa 传递的参数是按值传输,所以其值得变化不受影响
        }


(3):参数匹配


强语法类型的语言就是这样,类型不对,不好使。


在函数中,实参和形参类型不匹配,则会将形参的数据类型隐式的转换为实参的数据类型。


如果转换不了,报错。


/**
         * 定义一个静态函数
         */
        static int Sum(int a,int b)
        {
            int aa = a + b;
            return aa;
        }
        /**
         * 定义一个静态函数
         */
        static int Summ(byte a, int b)
        {
            int aa = a + b;
            return aa;
        }
static void Main(string[] args)
        {
            short one = 11;
            short two = 22;
            int res = Sum(one,two);
            Console.WriteLine(res); // 输出33
            int ult = Summ(one,two);
            Console.WriteLine(ult); // 报错:无法从“short”转换为“byte”
        }


(4):参数数组:


C#可以为函数方法指定一个特殊的参数,这个参数必须放在最后一个参数。被称为参数数组。参数数组允许使用不确定个数的数组来调用函数,使用params关键字指定。


定义函数:


public static int ArrayValue(params int[] value)
        {
            int res = 0;
            for (int i = 0; i < value.Length; i++)
            {
                res += value[i];
            }
            return res;
        }


调用:


// 参数数组
int result = ArrayValue(1,2,3,4,5);
Console.WriteLine(result);


3:递归函数


递归函数就是自己调用自己


5的阶乘:


/**
         * 定义一个递归函数
         */
        static int Digui(int a)
        {
            if (a < 1)
            {
                return 1;
            }
            else {
                return a * Digui(a - 1); //这是递归调用,自己调用自己
            }
        }
static void Main(string[] args)
        {
            int number = 5;
            int cvb = Digui(5);
            Console.WriteLine(cvb);
        }


测试使用全部代码:控制台应用程序


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace functions
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] srray = { 1,2,8,9,6,4,5,3,10,0};
            int maxData = GetMax(srray);
            Console.WriteLine(maxData);
            //int total = hanshu(1, 2, 3);// 1,2.3是实际参数
            //Console.WriteLine(total);  // 输出6
            /*int[] number = { 1,2,3,4,5};
            foreach (var item in number)
            {
                Console.WriteLine("传递前:{0}",item);
                /*传递前:1
                传递前:2
                传递前:3
                传递前:4
                传递前:5
            }
            // 调用函数
            Message(number);
            foreach (var item in number)
            {
                 Console.WriteLine("传递后:{0}",item);
                /*传递后:1
                传递后:4
                传递后:9
                传递后:16
                传递后:25
            }//*/
            /*int aa = 2;
            int bb = 3;
            int cc = 4;
            Refs(ref aa, ref bb, ref cc);
            Console.WriteLine(aa); // 4
            Console.WriteLine(bb); // 9
            Console.WriteLine(cc); // 16//*/
            /*int aaa = 52;
            int bbb;
            Mess(aaa,out bbb);
            Console.WriteLine(aaa); //52
            Console.WriteLine(bbb); //52
            // 在函数中将aaa的值附给了输出型参数bb,实参bbb与形参bb在同一内存中,所以值得改变会关联
            // aaa 传递的参数是按值传输,所以其值得变化不受影响//*/
            /*short one = 11;
            short two = 22;
            int res = Sum(one,two);
            Console.WriteLine(res); // 输出33
            int ult = Summ(one,two);
            Console.WriteLine(ult); // 报错:无法从“short”转换为“byte”//*/
            int number = 5;
            int cvb = Digui(5);
            Console.WriteLine(cvb);
            Console.WriteLine("-------------------------------------------------------");
            // 参数数组
            int result = ArrayValue(1,2,3,4,5);
            Console.WriteLine(result);
            Console.ReadKey();
        }
        public static int ArrayValue(params int[] value)
        {
            int res = 0;
            for (int i = 0; i < value.Length; i++)
            {
                res += value[i];
            }
            return res;
        }
        public static int GetMax(int[] array)
        {
            int maxValue = array[0];
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] > maxValue)
                {
                    maxValue = array[i];
                }
            }
            return maxValue;
        }
        /**
         * 定义一个静态函数
         */
        static int hanshu(int a, int b, int c)// 这里边的a,b,c是形式参数
        {
            int total = a + b + c;
            return total;
        }
        /**
         * 定义一个没有返回值的数组按地址传递的数组
         */
        static void Message(int[] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = array[i] * array[i];
            }
        }
        /**
        * 定义一个静态函数(引用性参数)
        */
        static void Refs(ref int a, ref int b, ref int c)// 这里边的a,b,c是形式参数
        {
            a = a * a;
            b = b * b;
            c = c * c;
        }
        /**
         * 定义一个静态函数(输出型参数)
         */
        static void Mess(int aa, out int bb)
        {
            int cc = aa;
            bb = aa;
            aa = 2 * cc;
        }
        /**
         * 定义一个静态函数
         */
        static int Sum(int a, int b)
        {
            int aa = a + b;
            return aa;
        }
        /**
         * 定义一个静态函数
         */
        static int Summ(byte a, int b)
        {
            int aa = a + b;
            return aa;
        }
        /**
         * 定义一个递归函数
         */
        static int Digui(int a)
        {
            if (a < 1)
            {
                return 1;
            }
            else
            {
                return a * Digui(a - 1); //这是递归调用,自己调用自己
            }
        }
    }
}


目录
相关文章
|
2月前
|
开发框架 .NET 程序员
C# 去掉字符串最后一个字符的 4 种方法
在实际业务中,我们经常会遇到在循环中拼接字符串的场景,循环结束之后拼接得到的字符串的最后一个字符往往需要去掉,看看 C# 提供了哪4种方法可以高效去掉字符串的最后一个字符
253 0
|
1月前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
115 65
|
5月前
|
数据采集 数据可视化 测试技术
C#生成Selenium测试报告:实用方法与技巧
在C#中使用Selenium进行自动化测试时,结合代理IP和ExtentReports能增强测试安全性和报告质量。安装必备工具如Selenium WebDriver、NUnit和ExtentReports。在测试设置中,配置代理(如亿牛云爬虫代理)以隐藏IP,通过ChromeOptions定制UserAgent,并添加Cookie。测试代码示例展示了如何打开网页、执行搜索并生成详细的测试报告。使用ExtentReports可创建可视化测试结果,便于团队分析。
C#生成Selenium测试报告:实用方法与技巧
|
2天前
|
C# UED SEO
C# 异步方法async / await任务超时处理
通过使用 `Task.WhenAny`和 `Task.Delay`方法,您可以在C#中有效地实现异步任务的超时处理机制。这种方法允许您在指定时间内等待任务完成,并在任务超时时采取适当的措施,如抛出异常或执行备用操作。希望本文提供的详细解释和代码示例能帮助您在实际项目中更好地处理异步任务超时问题,提升应用程序的可靠性和用户体验。
11 3
|
14天前
|
C# Python
使用wxpython开发跨平台桌面应用,对wxpython控件实现类似C#扩展函数处理的探究
【10月更文挑战第30天】使用 `wxPython` 开发跨平台桌面应用时,可以通过创建辅助类来模拟 C# 扩展函数的功能。具体步骤包括:1. 创建辅助类 `WxWidgetHelpers`;2. 在该类中定义静态方法,如 `set_button_color`;3. 在应用中调用这些方法。这种方法提高了代码的可读性和可维护性,无需修改 `wxPython` 库即可为控件添加自定义功能。但需要注意显式调用方法和避免命名冲突。
|
1月前
|
存储 C#
【C#】大批量判断文件是否存在的两种方法效率对比
【C#】大批量判断文件是否存在的两种方法效率对比
33 1
|
1月前
|
C#
C#的方法的参数传递
C#的方法的参数传递
14 0
|
1月前
|
数据可视化 程序员 C#
C#中windows应用窗体程序的输入输出方法实例
C#中windows应用窗体程序的输入输出方法实例
40 0
|
2月前
|
C#
C#一分钟浅谈:Lambda 表达式和匿名方法
本文详细介绍了C#编程中的Lambda表达式与匿名方法,两者均可用于定义无名函数,使代码更简洁易维护。文章通过基础概念讲解和示例对比,展示了各自语法特点,如Lambda表达式的`(parameters) =&gt; expression`形式及匿名方法的`delegate(parameters)`结构。并通过实例演示了两者的应用差异,强调了在使用Lambda时应注意闭包问题及其解决策略,推荐优先使用Lambda表达式以增强代码可读性。
40 8
|
3月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
74 0