1、函数
我们在上一篇文章介绍到,一个求解从1到100之内的素数的问题,当中提到一个概念为函数。在C语言中,我们称之为函数,但是在JAVA里面,我们称之为一个方法。
2、函数介绍
2.1 数学函数
不做过多介绍,是一些方法的封装,在C语言中封装了一些基本的算法,比如求解正弦和余弦等函数。
#include <math.h>
#include <stdio.h>
int main(void)
{
double pi = 3.1416;
printf("sin(pi/2)=%f\nln1=%f\n", sin(pi/2),
log(1.0));
return 0;
}
2.2 自定义函数
定义函数的语法,如下:
返回值类型 函数名(参数列表)
{
语句列表
}
int is_prime(int n)
{
int i;
for (i = 2; i < n; i++){
if (n % i == 0){
break;
}
}
if (i == n){
return 1;
}else{
return 0;
}
}
3、形参和实参
下面我们定义一个带参数的函数,我们需要在函数定义中指明参数的个数和每个参数的类型,定义参数就像定义变量一样,需要为每个参数指明类型,并起一个符合标识符命名规则的名字。
#include <stdio.h>
void print_time(int hour, int minute)
{
printf("%d:%d\n", hour, minute);
}
int main(void)
{
print_time(23, 59);
return 0;
}
我们调用print_time(23, 59)时,函数中的参数hour就代表23,参数minute就代表59。确切地说,当我们讨论函数中的hour这个参数时,我们所说的“参数”是指形参,当我们讨论传一个参数23给函数时,我们所说的“参数”是指实参。
一个基本的原理是:形参相当于函数中定义的变量,调用函数传递参数的过程相当于定义形参变量并且用实参的值来初始化。
4、局部变量和全局变量
我们把函数中定义的变量称为局部变量,由于形参相当于函数中定义的变量,所以形参也相当于局部变量。
与局部变量的概念相对的是全局变量( Global Variable) ,全局变量定义在所有的函数体之外,它们在整个程序开始之前分配存储空间,在程序结束时释放存储空间,所有函数都可以通过全局变量名访问它们
#include <stdio.h>
int hour = 23, minute = 59;
void print_time(void)
{
printf("%d:%d in print_time\n", hour, minute);
}
int main(void)
{
print_time();
printf("%d:%d in main\n", hour, minute);
return 0;
}
5、增量式开发
通过函数的知识,我们可以了解到,函数其实是一些常用功能,或者复用功能的代码封装。这里,我们提到一个增量式开发,与函数有重叠的地方。
增量式开发,我们可以先将一个比较大的功能,拆分成小功能,每个小功能可以使用一个函数来完成封装,那么这样就会简单很多,可以一个函数一个函数的完成,这样逐步累加,就完成了一个比较大的功能。
举一个很简单的例子,比如我们求解一个角的sin和cos值,那么我们就先定义两个函数,sinFunc和cosFunc,然后分别实现(不分先后),这样,两个函数都完成的时候,就完成了要求。
6、递归
递归是一个特殊的函数,它会在执行的过程中不断调用自己,它有两个限定条件:一是满足不断重复调用自己;二是必须要有一个终止条件。咋一看,跟我们的循环很相似,确实是这样,不过递归的情况更为特殊,它与循环的不同之处在于,递归是上一层需要依赖下一层的结果,而循环没有这样的要求。我们介绍一个最简单的递归程序,计算一个数的阶乘:
int factorial(int n)
{
if (n == 0)
return 1;
else {
int recurse = factorial(n-1);
int result = n * recurse;
return result;
}
}