C#学习笔记(五)——函数
一、定义和使用函数。
直接通过例子进行说明吧
class Program
{
static void Write()
{
Console.WriteLine("Test output from function");
} static void Main(string[] args)
{
Write();
Console.ReadKey();
}
}
1、函数的构架
(1)关键字:static 和 void
static与面向对象的思维有关系,我们在这里先默认每个函数都需要加上这个关键字;
void即使便是返回值为空的意思。、
(2)函数名后跟圆括号 e.g Write();
(3)圆括号里面可以有参数,这个放在后面再讨论,
(4)一个要执行的代码块,放在花括号里面。
2、返回值
(1)当函数返回一个值时,可以采用以下两种方式修改函数
a、在函数声明中指定返回值得类型,但不使用关键字void;
b、使用return关键字结束函数的执行,把返回值传送给调用代码。
static <returnType> <functionName>()
{
……
return <returnValue>;
}
(2)return 不一定要放在最后一行,也很经常用于直接跳出函数。
3、参数
(1)当函数接受参数的时候,就必须指定下列内容
a、函数在其定义指定接受的参数列表,以及这些参数的类型;
b、在每个函数调用中匹配的参数列表。
c、其中可以有任意多个参数,每个参数都有一个类型和一个名称,参数用逗号隔开。每个参数都在函数的代码中用作一个变量。
(2)一个demo
namespace Exercise
{
class Program
{
static int MaxValue(int[] intArray)
{
int maxVal = intArray[];
for(int i=;i<intArray.Length;i++)
{
if(intArray[i]>maxVal)
{
maxVal = intArray[i];
}
}
return maxVal;
} static void Main(string[] args)
{
int[] myArray = { , , , , , , , };
int maxVal = MaxValue(myArray);
Console.WriteLine("The maximum value in myArray is {0}", maxVal);
Console.ReadKey();
}
}
}
运行结果是:
(3)参数匹配
在调用函数时,必须使参数与函数定义中指定的参数完全匹配,这意味着要匹配参数的类型、个数和顺序。当然这样子会导致我们重复写同样的代码,仅仅是因为参数类型的小改变,但是后面我们会有传说中的重载函数来解决这个问题。
(4)参数数组
C#允许定义一个(只能指定一个)特定的参数,这个参数必须是函数定义中参数列表的最后一个,称之为参数数组。参数数组可以使用个数不定的参数调用函数,规定用关键字params关键字定义。
一个demo:
namespace Exercise
{
class Program
{
static int SumVals(params int[] vals)
{
int sum = ;
foreach (int val in vals)
{
sum += val;
}
return sum;
}
static void Main(string[] args)
{
int sum = SumVals(, , , , , , , , , );
Console.WriteLine(sum);
Console.ReadKey();
}
}
}
(5)引用参数和值参数
然后我们调用这个函数
我们会发现,我们对参数进行的double操作并不会影响Main()中的值
但是我们在这里有一个引用的方法,可以讲参数和引入变量绑定在一起,也就是说参数成为了引入变量的一个别名,实际上是一样的东东,方法就是使用ref关键字进行指定才参数。
然后在函数调用中我们需要再一次指定ref参数,demo如下
class Program
{
static void ShowDouble(ref int val)
{
val *= ;
Console.WriteLine("val doubled = {0}",val);
}
static void Main(string[] args)
{
int myNumeber = ;
Console.WriteLine("myNumber = {0}", myNumeber);
ShowDouble(ref myNumeber);
Console.WriteLine("myNumber = {0}", myNumeber); }
}
Attention:C#不允许假定ref参数在使用它的函数中初始化,也就是说调用的参数一定要有赋值过。
(6)输出参数
除了按引用传递值之外,还可以使用out关键字,指定所给的的参数是一个输出参数,out关键字和ref关键字的使用方法相同,执行的原理与引用参数一样,但是有一些重要的区别:
a、把未赋值的变量用作ref参数是非法的,但可以把未赋值的变量作out参数。
b、另外,在函数使用out参数时,out参数必须看成未赋值。换句话说,out参数会遗忘原有的数值。
现在写一个demo
class Program
{
static int MaxValue(int[] intArray,out int maxIndex)
{
int maxVal = intArray[];
maxIndex = ;
for(int i=;i<intArray.Length;i++)
{
if(intArray[i]>maxVal)
{
maxVal = intArray[i];
maxIndex = i;
}
}
return maxVal;
}
static void Main(string[] args)
{
int[] myArray = {,,,,,,,,,,,};
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);
Console.ReadKey();
}
}
二、变量的作用域
1、变量的作用域包含定义他们的代码块和直接嵌套在其中的代码块。(包括循环和条件语句)
namespace Exercise
{
class Program
{ static void Main(string[] args)
{
int i;
for(i=;i<;i++)
{
string text = "Line" + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
}
}
}
由于text是循环里的局部变量,所以跳出循环之后就不能在使用text了。然后修改一下
class Program
{ static void Main(string[] args)
{
int i;
string text;
for(i=;i<;i++)
{
text = "Line" + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
}
}
这段代码依旧会是编译出错,原因是必须在使用变量前对其进行声明和初始化,而text是在for循环里面初始化的,赋给text的值在循环快退出时就丢失了,但是还可以进行如下的修改
class Program
{ static void Main(string[] args)
{
int i;
string text="";
for(i=;i<;i++)
{
text = "Line" + Convert.ToString(i);
Console.WriteLine("{0}", text);
}
Console.WriteLine("Last text output in loop: {0}", text);
}
}
这次代码就是先在循环外进行了初始化。所以在这里我们需要掌握一个好的习惯就是在声明一个变量的时候最好是记得进行初始化,这样的话即使出错,我们也可以很容易的得知是那个变量出现了问题,还有就是避免这些问题的发生,
2、全局变量
这钟变量最好是少使用,一般我们也是很少进行使用的,尽量的进行避免。但是如果全局都需要经常访问的话,全局变量的优势就会体现出来。
在局部变量和全局变量的名字发生冲突的时候,局部变量会掩盖全局变量。
三、Main()函数
Main()是C#应用程序的入口和出口。就是说Main()函数是整个函数的框架。
1、Main()的四种形式
(1)第三四种版本会返回一个int值,他们可以用于表示程序如何终止,通常作为一种错误提示,如果是正常关闭的话,就是返回0。
(2)Main()的可选参数args是从应用程序的外部接受信息的方法,这些信息在运行期间指定,其形式是命令行参数。也就是说在执行控制台应用程序时,指定的任何命令参数都放在这个args数组中,然后可以根据需要在Main()中使用这些参数。
然后这里有个简单的demo
namespace Exercise
{
class Program
{ static void Main(string[] args)
{
Console.WriteLine("{0} command line argument were specified:", args.Length);
foreach(string arg in args)
{
Console.WriteLine(arg);
}
Console.ReadKey();
}
}
}
然后我们要在项目属性中进行设置,如图(在调试那一栏)
在命令参数行:我们可以加入很多的命令- -,在这里就随意加一点,只是实现这个功能而已,如果单词和单词之间有空格存在的话,我们就需要用“”括起来,这样子才不会被当成是多个命令。效果如图
四、结构函数
就是结构体中可以不仅仅可以加入变量,而且可以加入函数。那么我们就用一个demo来解决吧。
namespace Exercise
{
class Program
{
struct customerName
{
public string firstName, lastName; public string Name()
{
return firstName + " " + lastName;
}
} static void Main(string[] args)
{
customerName myCustomerName;
myCustomerName.firstName = "Chen";
myCustomerName.lastName = "Xuewen";
Console.WriteLine("{0}", myCustomerName.Name());
Console.ReadKey();
}
}
}
然后函数的可以在结构体内可以看做是全局函数。
五、函数的重载
重载就是“重复”,函数的重载也就是说函数可以有同样的名字,但是有着不同的功能,比如说如果我们要求一个数组里面的最大值,但是数组又有不同的类型,如果再取不同 的名字会很麻烦,于是哦我们就可以使用函数重载,保持函数名称不变,而实现功能。现在有个demo、
static int MaxValue(int[] intArray)
{
int maxVal = intArray[];
for(int i=;i<intArray.Length;i++)
{
if(intArray[i]>maxVal)
{
maxVal = intArray[i];
}
}
return maxVal;
} static double MaxValue(double[] doubleArray)
{
double maxVal = doubleArray[];
for (int i = ; i < doubleArray.Length; i++)
{
if (doubleArray[i] > maxVal)
{
maxVal = doubleArray[i];
}
}
return maxVal;
}
这两个函数就实现了函数的重载,但请注意,如果仅仅只是改变return(也就是返回值的类型)的类型,C#是不会认为是2个重载的函数,而是会发生错误。大家要小心
六、委托
委托的声明非常类似于函数,但是不带函数体,但是要使用delegate关键字,委托声明指定了一个返回类型和一个参数列表。
在定义了委托后,就可以声明该委托类型的变量,接着把这个变量初始化为与委托有相同返回类型和桉树列表的函数引用。之后就可以使用这个委托来调用这个函数,就像这个变量就是一个函数的样子。
namespace Exercise
{
class Program
{
delegate double ProcessDelegate(double param1, double param2);
//设置一个委托 static double Mulitiply(double param1, double param2)
{
return param1 * param2;
} static double Division(double param1,double param2)
{
return param1 / param2;
} static void Main(string[] args)
{
ProcessDelegate process;//声明一个委托(但是还没有绑定函数) //下面这段代码就是用来分割出来两个数字的- -,比C++麻烦很多- -
Console.WriteLine("Enter 2 number separated with a comma:");
string input = Console.ReadLine();
int commaPos = input.IndexOf(",");
double param1 = Convert.ToDouble(input.Substring(, commaPos));
double param2 = Convert.ToDouble(input.Substring(commaPos + , input.Length - commaPos - )); //选择功能
Console.WriteLine("Enter M to multiply or D to divide:");
input = Console.ReadLine();
input = input.ToUpper();
if(input == "M")
{
process = new ProcessDelegate(Mulitiply);
}
else
{
process = new ProcessDelegate(Division);
}
Console.WriteLine("Result:{0}", process(param1, param2)); Console.ReadKey();
}
}
}
然后委托主要是用于事件,这个在第13章中会用到哈。
C#学习笔记(五)——函数的更多相关文章
- Python学习笔记(五)函数和代码复用
函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Python提供了许多内建函数,比如print().同样,你也可以自己创建函数, ...
- Go语言学习笔记(五) [函数]
日期:2014年7月29日 1.函数定义:func (p type) funcname(q int) (r,s int) {return 0,0 } func: 保留字,用于定义一个函数 ...
- python学习笔记(五)---函数与类
函数 def为定义函数的一个标志 demo1: def greet_user(username): print("Hello, " + username.title() + &qu ...
- JS学习笔记 (五) 函数进阶
1.函数基础 1.1 函数的基本概念 函数是一段JavaScript代码,只被定义一次,但是可以被调用或者执行许多次.函数是一种对象,可以设置属性,或调用方法. 函数中的参数分为实参和形参.其中,形参 ...
- (转)Qt Model/View 学习笔记 (五)——View 类
Qt Model/View 学习笔记 (五) View 类 概念 在model/view架构中,view从model中获得数据项然后显示给用户.数据显示的方式不必与model提供的表示方式相同,可以与 ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- Typescript 学习笔记五:类
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- ES6学习笔记<五> Module的操作——import、export、as
import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...
- muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor
目录 muduo网络库学习笔记(五) 链接器Connector与监听器Acceptor Connector 系统函数connect 处理非阻塞connect的步骤: Connetor时序图 Accep ...
- python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍
python3.4学习笔记(五) IDLE显示行号问题,插件安装和其他开发工具介绍 IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.pycharm免费社区版.Su ...
随机推荐
- linux命令别名的使用
语 法:alias[别名]=[指令名称] 1,查看该用户下的别名: alias 2,有的系统里没有ll这个命令,原因就是没有定义ll='ls -l --color=tty'这个别名 如果想永久生效,就 ...
- 15个超实用的php正则表达式
在这篇文章里,我已经编写了15个超有用的正则表达式,WEB开发人员都应该将它收藏到自己的工具包. 验证域名 检验一个字符串是否是个有效域名. $url = "http://komunitas ...
- 关于git提交的自己的理解
包子不才,对于码云上的git的使用,自己的理解是 这个命令用于查看,哪些文件被修改了,以及修改了哪些地方, 这个命令用于增加你新添的文件,如果该文件已经存在,那么这一步则可以省略,随后就是commit ...
- angularjs中关于当前路由再次点击强制刷新
angularjs中,有一个机制,就是当前路由再次点击的时候,不会再刷新页面,这实在是愁坏了包子,因为业务人员要求一定要刷新,于是我各种百度,然并卵....呜呜呜~~~~~ 于是乎,我就想到写指令了, ...
- SQL例题合集
1. 查询Student表中的所有记录的Sname.Ssex和Class列. Select sname,ssex,class from student; 2. 查询教师所有的单位即不重复的Depart ...
- OpenSwitch操作系统成为Linux基金会官方项目
导读 非盈利机构Linux基金会为推进Linux和开源软件在企业和专业人士的发展,于今天宣布OpenSwitch项目成为Linux基金会官方项目之一. Linux基金会的常务董事Jim Zemlin表 ...
- [BZOJ1061][Noi2008]志愿者招募
[BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...
- redhat 6 / centos 6 搭建Django环境
1)首先 安装的时候 到 选择安装那些包的时候 把 编译环境和开发的包 那块全部打上勾 2)系统虽然自带Python安装包,但是版本比较低.所以推荐自行进行tar包编译安装比较新的 https:// ...
- 算法训练 Torry的困惑
问题描述 Torry从小喜爱数学.一天,老师告诉他,像2.3.5.7……这样的数叫做质数.Torry突然想到一个问题,前10.100.1000.10000……个质数的乘积是多少呢?他把这个问题告诉老师 ...
- 中位数与第K小元素
算法实际上是模仿快速排序算法设计出来的,其基本思想也是对输入数组进行递归划分,与快速排序不同的是,它只对划分出来的子数组之一进行递归处理: int randompartition(int a[],in ...