第五章函数
函数包括库函数和自定义函数。
函数的定义
由函数首部和函数体组成
函数首部由函数类型(即函数的结果类型)、函数名和形式参数表组成。如:double cylinder(double r,double h)
Ps:函数首部不能加分号,它和函数体一起构成完整的函数定义。
Ps:形参表不能写成double r,h。
函数体由一对大括号内的若干条语句组成,用于计算或完成特定的工作,并用return语句返回运算的结果。
函数的调用
1、函数的调用过程(详见P102)
2、函数调用形式:
(1)、赋值语句
如:volume=cylinder(radious,height);
(2)、输出函数的实参
printf("%f",cylinder(radious,height));
3、参数的传递
即程序运行时遇到函数的调用,实参的值依次传给形参。并且参数传递是单向的,只允许实参把值复制给形参,形参的值即使在函数中改变了,也不会反过来影响实参。
4、函数结果返回
return的作用:结束函数的运行;带着运算结果返回主调函数。
Ps:retrun语句只能返回一个值。
5、函数原型声明
/*采用辗转相除法求最大公约数的函数*/
#include <stdio.h>
int gcd(int m,int n);
int main(){
int M,N,h;
printf("输入M N:");
scanf("%d%d",&M,&N);
h=gcd(M,N);
printf("最大公约数为%d",h);
return 0;
}
int gcd(int m,int n){
int r,temp;
if(m<n){
temp=n;
n=m; //将m n数值调换
m=temp;
}
r=m%n;
while(r!=0){
n=r;
r=m%n;
}
return n;
}
/*运用自定义函数判断素数*/
#include <stdio.h>
#include <math.h>
int prime(int m);
int main(){
int M;
printf("需要判断的数字:");
scanf("%d",&M);
if(prime(M)==1){
printf("yes!");
}
if(prime(M)==0)
{
printf("no!");
}
return 0;
}
int prime(int m){
int i;
double limit;
limit=sqrt(m)+1;
if(m<=1){
return 0;
}else if(m==2){
return 1;
}else{
for(i=2;i<=limit;i++){
if(m%i==0){
//切记i=2
return 0;
}
}
}
return 1;
}
不返回结果的函数
该函数类型为void,由于函数没有返还结果,函数调用不可能出现在表达式中,通常以独立的调用语句方式。如:pyramid(n)。
局部和全局变量
C语言中把定义在函数内部的变量称为局部变量,局部变量的有效作用范围局限于所在的函数内部。这最大程度确保了各函数之间的独立性,避免函数之间相互干扰。
定义在函数外而不属于任何函数的变量称为全局变量。由于局部变量和全局变量作用范围不同,允许它们同名。但当某函数的局部变量和全局变量同名时,在该函数中全局变量不起作用,而局部变量起作用。在函数和复合语句同样成立。
变量生存周期
变量从定义开始分配储存单元,到运行结束储存单元被收回,整个过程称为变量生存周期。(变量的作用范围和生存周期是不同的概念)
静态变量
存在于静态存储区,不会像普通局部变量那样因为函数调用结束而被系统收回,它的生存周期会持续到程序结束。由于存储单元被保留,一旦含有静态局部变量的函数被再次调用,则静态局部变量会被重新激活,上一次函数调用后的值任然保存着,可供本次调用继续使用。
定义格式:
static 类型名 变量表
//详见P117
#include <stdio.h>
double fact_s(int n);
int main()
{
int i,n;
printf("input n:");
scanf("%d",&n);
for(i=1;i<=n;i++){
printf("%3d!=%.0f\n",i,fact_s(i));
}
return 0;
}
double fact_s(int n)
{
static double f=1;//定义静态变量,第一次赋值为1
f=f*n; //上一次调用时的值再乘n
return(f);
}
运行结果
注意点:
1、若没有赋初值,系统将会自动赋为0。
2、赋初值只在函数第一次调用时起作用,以后调用都按前一次调用保留的值使用。
3、变量范围受变量范围限制,只能用于所定义的函数,不能作用于其他函数。