第5章 函数
5.1 函数的概念和结构
先来比较两个概念:过程(procedure)、函数(function)。
过程与函数都是一组封装在一起的语句,能实现特定的功能。区别在于过程只进行某种操作,而函数会产生一个返回值。在C语言中,过程与函数的语法结构类似(在某些语言中是定义语句是不同的)。因此,C语言中的“过程”可以简单理解为没有返回值的函数。
过程语法结构如下:
void <函数名>(<参数>)
{
<语句>
return;
}
函数语法结构如下:
返回值类型 <函数名>(<参数>)
{
<语句>
return (开头定义的返回值类型的常量或变量);//例如:return 0;或return x;
}
下面的过程可以实现小车右转:
void littleright(double number1, double number2)
{
digitalWrite(11,1); analogWrite(10,number1);
digitalWrite(8,0); analogWrite(9,number1);
_delay((number2) * (0.1));
return;
}
显然,笔者并不希望“右转”这个动作有什么返回值。而在上述过程中,笔者使用了其他过程如digitalWrite()等。括号中用逗号隔开的是过程的参数。笔者自己定义的过程中也存在参数。参数的数量和数据类型不受限制,不过通常不会很多。
函数的意义在于方便。首先方便了我们实现某种操作。比如一个小车程序中可能需要多次右转,有了函数则只需调用相应次数并在使用的时候修改参数。而如果复制代码然后修改相应变量,工作量大到难以忍受。其次是方便我们修改。更重要的其实是……好看。可读性是大规模程序需要着重注意的点。
5.2 函数的使用
使用函数时,我们必须知道它的参数个数,类型,参数的顺序,以及返回值的类型。
例如:z=pow(x,y);
上面的语句运行之后,z这个变量中储存的就是x的y次方的值。z,x,y应当都是整形或浮点型。x若为负数则y不能为小于1大于0的数,若x等于0则y不能小于等于0。如果单纯写pow(x,y);显然毫无意义。但我们可以写printf(“%d”,pow(x,y));(假设x,y为正整数)来让屏幕上输出x的y次方的值。
我们自己定义的过程和函数与头文件中包含的函数在调用的时候没有不同。
5.3 局部变量和全局变量
这个内容应该早点说的。简单点说,定义在某对{}里的变量,可以在这对{}中的{}中的语句中使用。全局变量直接定义在函数体外,不在任何一对{}之内,所以全局变量可以在任何语句中使用。例如:
#include<iostream>
#include<cstdio>
using namespace std;
int f[40001];
struct node{
int x,y,v;
}e[20001];
bool cmp(node a,node b) { return a.v>b.v; }
int find(int x) { return f[x]==x?x:f[x]=find(f[x]); }
int main()
{
int n,m;
cin >> n >> m;
for (int i=1; i<=m; i++) cin >> e[i].x >> e[i].y >> e[i].v;
for (int i=1; i<=2*n; i++) f[i]=i;
sort(e+1,e+m+1,cmp);
for (int i=1; i<=m; i++)
{
int xx=find(e[i].x);
int yy=find(e[i].y);
if (xx==yy) { cout << e[i].v << endl; system("pause"); return 0;}
f[xx]=find(e[i].y);
f[yy]=find(e[i].x);
}
cout << 0; return 0;
}
全局变量为数组f和数组e(数组的知识在下一章,总之也是一种数据结构)。在main函数中定义了变量n,m。在循环语句中定义了变量i。那么i就只能在那一个循环语句中用。在后面的语句中我重复定义了很多次i。n,m则可以在整个main函数中用。至于f和e数组,可以在程序的任意一个函数中用。
需要注意的是,有的编译器要求变量必须在函数语句的第一行(或者说任何语句的前面)定义完成,而不允许在执行语句中穿插。同时,浮点型和整型全局变量的初始值默认为0。