s+=b[k][k]+b[k][n-k];
returns;}
7.5局部变量和全局变量
7.5.1局部变量及其概念
1.形参是局部变量。
2.在一个复合语句中定义的变量。
3.在一个函数中定义的变量。
7.5.2全局变量及其概念
1.函数外部定义的变量。
2.用extern说明的变量。
例:
全局变量,一方变化,都变化
intm,n;
main()
{m=3,n=5;
printf("%d%d\n",m,n);
abc();
}
abc()
{
printf("%d%d",m,n);
}
例:
有全局变量与局部变量相同,局部变量优先
给出下列程序的运行结果:
intm=3,n=5;
main()
{intm=30,n=50;/*无此句,一方变化都变化,有此句,局部优先
clrscr();
abc();
printf("%d%d\n",m,n);
abc();
}
abc()
{
m=15,n=17;
printf("%d%d\n",m,n);
}
7.6动态存储变量及静态存储变量
7.6.1动态变量
1.程序运行期间,分配内存单元,运行结束,内存单元就释放。
2.形参、局部变量都是动态变量。
3.动态变量用auto说明或省略。
7.6.2静态变量
1.调用函数结束,变量值保留,下次调用值仍存在。
2.静态变量用static说明。
3.数组只有定义成静态时,才能初始化。
4.静态变量自动赋0值。
5.何时需要定义静态数组:
保留函数的变量值和数组初始化。
例:
读程序,给出运行结果
main()
{intk;
clrscr();
for(k=1;k<5;k++)
printf("%d\n",f(k));
}
intf(intn)
{intk;
staticintf=1;/*静态变量f,保留上次计算结果
for(k=1;k<=n;k++)
f=f*k;
returnf;
}
7.7寄存器变量
作用:
存取速度快。
特点:
只允许使用三个寄存器变量,且必须是形参和局部变量才能使用。
用法:
用register说明。
intf(intn)
{registerk,f=1;
for(k=1;k<=n;k++)
f=f*k;
returnf;
}
7.8内部函数
放在一个文件中的函数称为内部函数。
7.9外部函数
文件独立存放,能被其他文件中调用的函数称为外部函数。
外部函数在调用程序中要用头文件说明。
7.10函数递归
函数自身调用自身
举例:
1.计算年龄
程序:
main()
{printf(“age=%d\n”,age(4));
}
intage(intn)
{intc;
if(n==1)c=16;
elsec=age(n-1)+2;
returnc;
}
2.计算1+2+3+……+100
main()
{printf("age=%d\n",age(100));
}
intsum(intn)
{intc;
if(n==1)c=1;
elsec=sum(n-1)+n;
returnc;
}
3.计算n!
(c=f(n-1)*n)
4.计算0,1,1,2,3,5,8,…..第前20项(return(f(n-1)+f(n-2));)
main()
{printf("age=%d\n",num(19));
}
intnum(intn)
{intc;
if(n==1)c=0;
elseif(n==2)c=1;
elsec=num(n-1)+num(n-2);
returnc;
}
函数递归的两个基本条件
(1)边界条件
(2)递归表达式
5.求两个正整数的最大公约数
intgys(intm,intn)
{intr;
r=m%n;
if(r==0)returnn;
gys(n,r);
}
main()
{printf(“%d”,gys(24,16));
}
设计一个过程:
能产生Fibonacci序列数的N个数,即01123581321...。
用主调函数过程调用这个过程并完成:
找出所有是偶数的Fibonacci数,计算这些偶数的平均值。
任务:
设计子过程,产生序列数。
设计主过程,找偶数,统计,求平均值
longfib(inta,b)
{return(a+b);}
main()
{longn=18,a=0,b=1;k;
longp=0,num=0
For(k=1;k<=n;k++)
{=fib(a,b);
if(a%2==0)p+=a;num+=1;
}
Printf(“average=%f\n”,(float)num/n);
}
设计一个过程:
求两个正整数的最小公倍数。
在主调函数过程中调用这个过程并求m,n的最小公倍数
设计一个过程:
判定任意正整数是否素数。
在主调函数过程中调用这个过程并求出[100,200]范围内的素数的个数。
intprimes(intm)
(intk;
For(k=2;kIf(m%k==0)break;
If(k==m)return1elsereturn0;
}
main()
{intj,n=0;
for(j=100;j<200,j++)
if(primes(j))n++;
printf(“primesisin100-200=%d”,n)
}
7.11多文件程序的运行
方法一:
建立多个*.c文件(说明型,项目文件型),按顺序放在#include中。
例:
f1.c输出“11111”
f2.c输出“22222”
f3.c调用f1.c,f2.c,再输出“33333”
例:
方法一
/*f3*/
#include“f1.c”/*文件名*/
#include“f2.c”
main()
{p1();p2();/*函数名*/
clrscr();
printf(“33333\n”);}
/*f1.c*//*文件名*/
p1()/*函数名*/
{printf(“11111”\n);}
/*f2.c*/
p2()
{prinf(“22222”);}
方法二、
1.分别建立子函数文件:
f1.c,f2.c,f3.c
2.建立项目文件,文件名后缀一定是*.prj
/*a.prj*/
f1.cf2.cf3.c
或
/*a.prj*/
f1.c
f2.c
f3.c
用save保存为a.prj
将project菜单项中的*.prj改为a.prj
3.编译连接(f9)
4.运行(Ctrlf9)
/*f3*/
main()
{externp1(),p2();
clrscr();
printf(“33333\n”);}
/*f1.c*/
p1()
{printf(“11111”\n);}
/*f2.c*/
p2()
{prinf(“22222”);}
方法三:
用extern说明函数为外部函数
例:
求m的n次方(使用方法一)
/*ncf.c*/
#include“ncf.c”
main()
{
externlongnpow(floata,intn)
clrscr();
printf(“npow=%ld\n”,npow(3,3));
}
/*ncf.c*/
externlongnpow(floata,intn)
{longi,k=1;
for(i=1;i<=n;i++)
k=k*a;
return(k);}
例:
统计英文句子中L出现的次数(绘制流程图)。
main()
{chara[80];
intk,n=0;
scanf(“%s”,a);
for(k=0;a[k];k++)
if(a[k]==’l’||a[k]==’L’)n++;
printf(“%d\n”,n);
}
数值算法应用举例;
题1:
用普通迭代法求方程f(x)=x+lnx-1.56=0的近似实根r,迭代初值为2,精确到0.0001。
说明:
将f(x)=0转换成x=g(x)形式
x=1.56-lnx
#include“math.h”
main()
{floatx0,x1=2;
do
{x0=x1;
x1=1.56-log(x0);}
while(fabs(x1-x0)>1e-3);
printf(“%f”,x1);
}
题2:
用牛顿迭代法求方程2x3-4x2+3x-6=0在1.5附近的根
(2)。
f(x)=2x3-4x2+3x-6=0
f’(x)=6x2-8x+3=0
#include“math.h”
main()
{floatx0,x1=1.5;
floatf(floatx)
floatf1(floatx)
do
{x0=x1;x1=x0-f(x0)/f1(x0);}
while(fabs(x1-x0)>0.0001);}
printf(“%f\n”,x1);}
floatf(floatx)
{return(2*x*x*x-4*x*x+3*x-6);}
floatf1(floatx)
{return(6*x*x-8*x+3);}
题3:
用牛顿迭代法求方程x=
从1-10的平方根的根.
x2=a
f(x)=x2-a=0
迭代式:
xn+1=(xn+a/xn)/2
#include“math.h”
main()
{floata,x0,x1;
for(a=1;a<11;a++)
{x1=a;
do
{x0=x1;x1=(x0+a/x0)/2;}
while(fabs(x1-x0)>0.0001);
printf(“%f\n”,x1);}
}
题4:
用矩形法求一元函数f(x)=ln(x+1)+x/2,在区间[1,5]上的积分近似值S,保留2位小数
main()
{floata=1,b=5,x,sum=0,h.n=100;
H=(b-a)/n;
For(x=a;x
sum+=log(x+1)+x/2;
printf(“%f\n”,sum*h);
}
题5:
用梯形法求一元函数f(x)=ln(x+1)+x/2,在区间[1,5]上的积分近似值S,保留2位小数
方法一:
main()
{floata=1,b=5,x,sum=0,h.n=100,d1,d2;
H=(b-a)/n;
For(x=a;x
{d1=log(x+1)+x/2;
d2=log(x+h+1)+(x+h)/2;
sum+=d1+d2;}
printf(“%f\n”,sum*h/2);
}
方法二:
main()
{floata=1,b=5,x,sum=0,h.n=100;
H=(b-a)/n;
For(x=a+h;x
sum+=log(x+1)+x/2;}
sum=log(a)+a/2+log(b)+b/2+sum*2;
printf(“%f\n”,sum*h/2);
}
题6:
用梯形法求积分
近似值S,保留2位小数
#include“math.h”
main()
{floata=0,b=1.57,x,sum=0,h,n=100;
h=(b-a)/n;
for(x=a+h;x
sum+=sin(x);
sum=sin(a)+sin(b)+sum*2;
printf(“%4.2f\n”,sum*h/2);
}