方法
定义
一个方法(函数)是把一些相关的语句组织在一起,用来执行一个任务的语句块。每一个 C# 程序至少有一个带有 Main 方法的类。
方法就是将一堆代码进行重用的机制
要使用一个方法,您需要:
- 定义方法
- 调用方法
语法
[public] static 返回值类型 方法名 ([参数列表])
{
方法体;
}
public 访问修饰符
static 静态的
返回值类型:如果没有返回值写 void
方法名:符合Pascal命名规范
参数列表:完成这个方法所必须的条件
方法的调用:准确的说是静态方法的调用
类名.方法名
在某些情况下,类名可以省略,如果你写的方法跟Main()函数在同一个类中这个时候可以省略
public static void Test()
{
Console.WriteLine("C#中学到的第一个方法");
}
写一个方法计算两个数中的最大值
static void Main(string[] args)
{
//计算两个整数之间的最大值
int max = Program.GetMax(1, 3);//实参
Console.WriteLine(max);
Console.ReadKey();
}
/// <summary>
/// 计算两个整数之间的最大值并且将最大值返回
/// </summary>
/// <param name="n1">第一个整数</param>
/// <param name="n2">第二个整数</param>
/// <returns>将最大值返回</returns>
public static int GetMax(int n1, int n2)
{
//这里边 两个参数是形参
return n1 > n2 ? n1 : n2;
}
求闰年方法
static void Main(string[] args)
{
//举例:写一个方法,判断一个年份是否是润年.
bool b = IsLeapYear(2000);
Console.WriteLine(b);
Console.ReadKey();
}
/// <summary>
/// 判断给定的年份是否是闰年
/// </summary>
/// <param name="year">要判断的年份</param>
/// <returns>是否是闰年</returns>
public static IsLeapYear(int year)
{
bool b = (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
return b;
}
//多次调用(如果用户输入的是数字,则返回,否则提示用户重新输入)
static void GetNumber()
{
while (true)
{
Console.WriteLine("请输入一个数字");
try
{
int number = Convert.ToInt32(Console.ReadLine());
Console.WriteLine(number);
break;
}
catch
{
Console.WriteLine("请重新输入");
}
}
}
上面这种写法有误,方法的功能要单一,方法中最忌讳出现提示用户输入的字眼
下面是正确的写法
class Program
{
static void Main(string[] args)
{
//1 读取输入的整数
//多次调用(如果用户输入的是数字,则返回,否则提示用户重新输入)
Console.WriteLine("请输入一个数字");
string input = Console.ReadLine();
int number = GetNumber(input);
Console.WriteLine(number);
Console.ReadKey();
}
/// <summary>
/// 这个方法需要判断用户的输入是否是数字
/// 如果是数字,则返回
/// 如果不是数字,提示用户重新输入
/// </summary>
public static int GetNumber(string s)
{
while (true)
{
try
{
int number = Convert.ToInt32(s);
return number;
}
catch
{
Console.WriteLine("请重新输入");
s = Console.ReadLine();
}
}
}
}
方法的两个练习
class Program
{
static void Main(string[] args)
{
//1 只允许用户输入y或n,只要不是,就重新输入
Console.WriteLine("请输入yes或者no");
string str = Console.ReadLine();
string result = IsYerOrNo(str);
Console.WriteLine(result);
Console.ReadKey();
//2计算输入数组的和:int Sum(int[] values)
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int sum = GetSum(nums);
Console.WriteLine(sum);
Console.ReadKey();
}
/// <summary>
/// 计算一个整数类型数组的总和
/// </summary>
/// <param name="nums">要求总和的数组</param>
/// <returns>返回这个数组的总和</returns>
public static int GetSum(int[] nums)
{
int sum = 0;
for (int i = 0; i < nums.Length; i++)
{
sum += nums[i];
}
return sum;
}
/// <summary>
/// 限定用户只能输入yes或者no 并且返回
/// </summary>
/// <param name="input">用户的输入</param>
/// <returns>返回yes或者no</returns>
public static string IsYerOrNo(string input)
{
while (true)
{
if (input == "yes" || input == "no")
{
return input;
}
else
{
Console.WriteLine("只能输入yes或者no,请重新输入");
input = Console.ReadLine();
}
}
}
}
out、ref、params
1. out参数
如果你在一个方法中,返回多个相同类型的值的时候,可以考虑返回一个数组。
但是,如果返回多个不同类型的值的时候,返回数组就不行了,那么这个时候,
我们可以考虑使用out参数。
练习:写一个方法 求一个数组中的最大值、最小值、总和、平均值
当返回同一个类型多个返回值的时候,可以用数组
/// <summary>
/// 计算一个数组的最大值、最小值、总和、平均值
/// </summary>
/// <param name="nums"></param>
/// <returns></returns>
public static int[] GetMaxMinSumAvg(int[] nums)
{
int[] res = new int[4];
//假设 res[0] 最大值 res[1]最小值 res[2]总和 res[3]平均值
res[0] = nums[0];//max
res[1] = nums[0];//min
res[2] = 0;//sum
string name = "孙全";
bool b = true;
for (int i = 0; i < nums.Length; i++)
{
//如果当前循环到的元素比我假定的最大值还大
if (nums[i] > res[0])
{
//将当前循环到的元素赋值给我的最大值
res[0] = nums[i];
}
if (nums[i] < res[1])
{
res[1] = nums[i];
}
res[2] += nums[i];
}
//平均值
res[3] = res[2] / nums.Length;
return res;
}
思考:如果返回不同类型该怎么办?
/// <summary>
/// 计算一个整数数组的最大值、最小值、平均值、总和
/// </summary>
/// <param name="nums">要求值得数组</param>
/// <param name="max">多余返回的最大值</param>
/// <param name="min">多余返回的最小值</param>
/// <param name="sum">多余返回的总和</param>
/// <param name="avg">多余返回的平均值</param>
public static void Test(int[] nums, out int max, out int min, out int sum, out int avg, out bool b, out string s, out double d)
{
//out参数要求在方法的内部必须为其赋值
max = nums[0];
min = nums[0];
sum = 0;
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] > max)
{
max = nums[i];
}
if (nums[i] < min)
{
min = nums[i];
}
sum += nums[i];
}
avg = sum / nums.Length;
b = true;
s = "123";
d = 3.13;
}
out参数的练习
//分别的提示用户输入用户名和密码
//你写一个方法来判断用户输入的是否正确
//返回给用户一个登陆结果,并且还要单独的返回给用户一个登陆信息
//如果用户名错误,除了返回登陆结果之外,还要返回一个 “用户名错误”
//“密码错误”
class Program
{
static void Main(string[] args)
{
//分别的提示用户输入用户名和密码
//你写一个方法来判断用户输入的是否正确
//返回给用户一个登陆结果,并且还要单独的返回给用户一个登陆信息
//如果用户名错误,除了返回登陆结果之外,还要返回一个 "用户名错误"
//“密码错误”
Console.WriteLine("请输入用户名");
string userName = Console.ReadLine();
Console.WriteLine("请输入密码");
string userPwd = Console.ReadLine();
string msg;
bool b = IsLogin(userName, userPwd, out msg);
Console.WriteLine("登陆结果{0}",b);
Console.WriteLine("登陆信息{0}",msg);
Console.ReadKey();
}
/// <summary>
/// 判断登陆是否成功
/// </summary>
/// <param name="name">用户名</param>
/// <param name="pwd">密码</param>
/// <param name="msg">多余返回的登陆信息</param>
/// <returns>返回登陆结果</returns>
public static bool IsLogin(string name, string pwd, out string msg)
{
if (name == "admin" && pwd == "888888")
{
msg = "登陆成功";
return true;
}
else if (name == "admin")
{
msg = "密码错误";
return false;
}
else if (pwd == "888888")
{
msg = "用户名错误";
return false;
}
else
{
msg = "未知错误";
return false;
}
}
}
2. ref参数
能够将一个变量带入一个方法中进行改变,改变完成后,再讲改变后的值带出方法。
ref参数要求在方法外必须为其赋值,而方法内可以不赋值。
//假如有这样一个方法
class Program
{
static void Main(string[] args)
{
double salary = 5000;
JiangJin(ref salary);
Console.WriteLine(salary);
Console.ReadKey();
}
public static void JiangJin(ref double s)
{
s += 500;
}
public static void FaKuan(double s)
{
s -= 500;
}
}
3. params可变参数
将实参列表中跟可变参数数组类型一致的元素都当做数组的元素去处理。
params可变参数必须是形参列表中的最后一个元素。
static void Main(string[] args)
{
int[] s={99,88,77};
Test("张三",s);
//
Test("张三",99,88,77);//会报错
}
static void Test(string name, int[] score)
{
int sum=0;
for(i=0; i<score.Length; i++)
{
sum+=socre[i]
}
Console.WriteLine($"{name}这次考试的成绩是{sum}");
}
用params修改方法,注意params修饰的参数必须放在方法中的最后一个参数
public static void Test(string name, int id, params int[] score)
{
int sum = 0;
for (int i = 0; i < score.Length; i++)
{
sum += score[i];
}
Console.WriteLine("{0}这次考试的总成绩是{1},学号是{2}", name, sum, id);
}
练习://求任意长度数组的和 整数类型的
static void Main(string[] args)
{
//求任意长度数组的和 整数类型的
int[] nums = { 1, 2, 3, 4, 5 };
int sum = GetSum(8,9);
Console.WriteLine(sum);
Console.ReadKey();
}
public static int GetSum(params int[] n)
{
int sum = 0;
for (int i = 0; i < n.Length; i++)
{
sum += n[i];
}
return sum;
}
方法的重载
概念:方法的重载指的就是方法的名称相同,但是参数不同。
参数不同,分为两种情况
1)、如果参数的个数相同,那么参数的类型就不能相同。
2)、如果参数的类型相同,那么参数的个数就不能相同。
方法的重载跟返回值没有关系。
class Program
{
static void Main(string[] args)
{
// M()
Console.WriteLine(1);
Console.WriteLine(1.4);
Console.WriteLine(true);
Console.WriteLine('c');
Console.WriteLine("123");
Console.WriteLine(5000m);
Console.ReadKey();
}
public static void M(int n1, int n2)
{
int result = n1 + n2;
}
//public static int M(int a1, int a2)
//{
// return a1 + a2;
//}
public static double M(double d1, double d2)
{
return d1 + d2;
}
public static void M(int n1, int n2, int n3)
{
int result = n1 + n2 + n3;
}
public static string M(string s1, string s2)
{
return s1 + s2;
}
}
方法的递归
方法自己调用自己。
找出一个文件夹中所有的文件。
class Program
{
static void Main(string[] args)
{
TellStory();
Console.ReadKey();
}
public static void TellStory()
{
//int i = 0;
Console.WriteLine("从前有座山");
Console.WriteLine("山里有座庙");
Console.WriteLine("庙里有个老和尚和小和尚");
Console.WriteLine("有一天,小和尚哭了,老和尚给小和尚讲了一个故事");
TellStory();
}
}
此时方法会进入死循环,此时设定一个变量记录讲10次方法就结束
class Program
{
static void Main(string[] args)
{
TellStory();
Console.ReadKey();
}
public static void TellStory()
{
int i = 0;
Console.WriteLine("从前有座山");
Console.WriteLine("山里有座庙");
Console.WriteLine("庙里有个老和尚和小和尚");
Console.WriteLine("有一天,小和尚哭了,老和尚给小和尚讲了一个故事");
i++;
if (i >= 10)
{
return;
}
TellStory();
}
}
当前方法依然是一个死循环,调试发现每次i都重新变为0
再次修改
class Program
{
static void Main(string[] args)
{
TellStory();
Console.ReadKey();
}
public static int i = 0;
public static void TellStory()
{
//int i = 0;
Console.WriteLine("从前有座山");
Console.WriteLine("山里有座庙");
Console.WriteLine("庙里有个老和尚和小和尚");
Console.WriteLine("有一天,小和尚哭了,老和尚给小和尚讲了一个故事");
i++;
if (i >= 10)
{
return;
}
TellStory();
}
}
方法的综合练习
class Program
{
static void Main(string[] args)
{
//提示用户输入两个数字 计算这两个数字之间所有整数的和
//1、用户只能输入数字
//2、计算两个数字之间和
//3、要求第一个数字必须比第二个数字小 就重新输入
Console.WriteLine("请输入第一个数字");
string strNumberOne = Console.ReadLine();
int numberOne = GetNumber(strNumberOne);
Console.WriteLine("请输入第二个数字");
string strNumberTwo = Console.ReadLine();
int numberTwo = GetNumber(strNumberTwo);
//判断第一个数字是否小于第二个数字
JudgeNumber(ref numberOne, ref numberTwo);
//求和
int sum = GetSum(numberOne, numberTwo);
Console.WriteLine(sum);
Console.ReadKey();
}
public static void JudgeNumber(ref int n1, ref int n2)
{
while (true)
{
if (n1 < n2)
{
//复合题意
return;
}
else//>=2
{
Console.WriteLine("第一个数字不能大于或者等于第二个数字,请重新输入第一个数字");
string s1 = Console.ReadLine();
//调用GetNumber
n1 = GetNumber(s1);
Console.WriteLine("请重新输入第二个数字");
string s2 = Console.ReadLine();
n2 = GetNumber(s2);
}
}
}
public static int GetNumber(string s)
{
while (true)
{
try
{
int number = Convert.ToInt32(s);
return number;
}
catch
{
Console.WriteLine("输入有误!!!请重新输入");
s = Console.ReadLine();
}
}
}
public static int GetSum(int n1, int n2)
{
int sum = 0;
for (int i = n1; i <= n2; i++)
{
sum += i;
}
return sum;
}
}