、第八章第一次作业需要注意的问题 (1)主函数和子函数的N-S图都要画,且要分开画 (2)子函数的NS图外要给出完整的具体的函数头,返回值类型、参数类型及参数名等都不能 省略。调用处只需且必须给岀具体的完整的语句,要传递的实参不能省略,且不能要类型说明 符。此外要注意参数个数。 如求一元二次方程的根,当deta<0时,若用如下方法则需要三个参数,因a、b和deta的 值在子函数都用到,三者都需要从调用处传递过来。此时,对应函数头为void smaller than zero( float a, float b, float deta),主函数中发生调用的位置写“ smaller than zero(a,b, de 主函数:输入a/b/c的值调用相应函数求根 /*当deta<0时求根并且输出* 输入abc void smaller than zero(float a, float b, float deta deta=b*b-4*aFc Deta<o L输出pq与pqi smaller than z 注意不能写“xl=p+q输出x1”,因无复数类型 ero(a, b, deta) 若用如下方法则只需两个参数,因子函数中只有a和b需要从调用处传递过来,此时,对 应函数头为 void smaller than zero( float a, float b),主函数中发生调用的位置写 主函数:输入a/b/c的值调用相应函数求根 当deta<0时求根并且输出* 输入abc void smaller than zero(float a, float b) deta=b*b-4*a**c 输出pqi与 (3)尽量避免用全局变量,确实需要用时,要在主函数N-S图的开始说明哪些是全局变量。 (4)变量名与函数名不能相同,且都不能与系统的保留字(如 int long for goto if等)重 复 (5)子函数头中已经定义的形参不能在子函数体内重新定义,且形参的值由调用语句中的对应 实参(按顺序对应)传递过来,通常不需重新赋初值。 (6)主函数或者子函数两者至少要有一个有输出,否则,整个程序无输出! (7)函数功能划分要合理,各自相互独立。 (8)8.16输入一个十六进制串,求对应的十进制并输出,可参考如下答案: 主函数将十六进制串输入字符数组s,之后判断str是否合法,合法则调用函数求对应十进制数并输出* 0n/n为1代表字符合法/判断字符是否十六进制合法字符,是则返回1,否则返回0+ hile(str[1=\0' int judge( char c) ae= judge(stray*返回值要接收并利用 本函数N-S图省略,自己补充 f== /*将十六进制字符串转化为十进制数并返回* break id trans( char sl 本函数NS图参考指导书中对应子函数中NS图,此外,指 导书中该题的主函数NS图中,EOF应改作n’,且指导书中的 输出不 答案也正确。 合法!puts(st) 注意:当子函数有返回值时,调用语句处要把该返回值接收并利用起来,如fag= judge(str[)
一、第八章第一次作业需要注意的问题: (1)主函数和子函数的 N-S 图都要画,且要分开画 (2)子函数的 N-S 图外要给出完整的具体的函数头,返回值类型、参数类型及参数名等都不能 省略。调用处只需且必须给出具体的完整的语句,要传递的实参不能省略,且不能要类型说明 符。此外要注意参数个数。 如求一元二次方程的根,当 deta<0 时,若用如下方法则需要三个参数,因 a、b 和 deta 的 值在子函数都用到,三者都需要从调用处传递过来。此时,对应函数头为 void smaller_than_zero(float a,float b,float deta),主函数中发生调用的位置写“smaller_than_zero(a, b, deta)” 若用如下方法则只需两个参数,因子函数中只有 a 和 b 需要从调用处传递过来,此时,对 应 函 数 头 为 void smaller_than_zero(float a,float b) ,主函数中发生调用的位置写 “smaller_than_zero(a, b)” (3)尽量避免用全局变量,确实需要用时,要在主函数 N-S图的开始说明哪些是全局变量。 (4)变量名与函数名不能相同,且都不能与系统的保留字(如 int long for goto if 等)重 复 (5)子函数头中已经定义的形参不能在子函数体内重新定义,且形参的值由调用语句中的对应 实参(按顺序对应)传递过来,通常不需重新赋初值。 (6)主函数或者子函数两者至少要有一个有输出,否则,整个程序无输出! (7)函数功能划分要合理,各自相互独立。 (8)8.16 输入一个十六进制串,求对应的十进制并输出,可参考如下答案: /*主函数将十六进制串输入字符数组 s,之后判断 str 是否合法,合法则调用函数求对应十进制数并输出*/ 注意:当子函数有返回值时,调用语句处要把该返回值接收并利用起来,如 flag=judge(str[i]), 输入 a b c deta=b*b-4*a*c Deta<0 Y N smaller_than_z ero(a,b,deta) ………….. 主函数:输入 a/b/c 的值调用相应函数求根 输入 a b c deta=b*b-4*a*c Deta<0 Y N smaller_than_z ero(a,b) ………….. 主函数:输入 a/b/c 的值调用相应函数求根 p=-b/(2*a) q=sqrt(-(b*b-4*a*c))/(2*a) 输出 p+qi 与 p-qi void smaller_than_zero(float a,float b) /*当 deta<0 时求根并且输出*/ p=-b/(2*a) q=sqrt(-deta)/(2*a) 输出 p+qi 与 p-qi void smaller_than_zero(float a,float b,float deta) /*当 deta<0 时求根并且输出*/ 注意不能写“x1=p+qi,输出 x1”,因无复数类型 gets(str) i=0;flag/*flag 为 1 代表字符合法*/ while(str[i]!=’\0’) flag=judge(str[i])/*返回值要接收并利用*/ flag= =0 Y N break flag= =0 Y 输出不 合法! N trans(str)/**/ puts(str) /*判断字符是否十六进制合法字符,是则返回 1,否则返回 0*/ int judge(char c) 本函数 N-S 图省略,自己补充 /*将十六进制字符串转化为十进制数并返回*/ void trans(char s[]) 本函数 N-S 图参考指导书中对应子函数中 N-S 图,此外,指 导书中该题的主函数 N-S 图中,EOF 应改作’\n’,且指导书中的 答案也正确
否则,如只写 judge(st)则此次函数调用毫无意义,因返回值未被利用;有时不必如此,如子 函数返回值类型为空时,此时调用语句可直接写tans(sm),如输出欢迎界面的子函数,只需输出 一个界面即可,无需返回值:再如数组名作函数参数时,因主调函数和被调函数中的数组是同 个数组,在子函数中对数组加以改变,原函数中的数组也相应改变,故此时无返回原数组也 发生了改变! (9)求最长单词并输出一题提示:设一个标记变量fag,用fag=0或1代表前一个字符是否 空格,当且仅当前一个字符是空格,且当且字符是字母代表单词开始。当前一个字符不是字母 而当且字符不是字母是单词结束 第二次作业说明 递归法NS图画法,如求n!对应的N-S图如下 主函数:输入n,调用递归函数f求n! 输出 /*递归法求阶乘子函数* int f(int m) 或 return m return(x 说明:数组元素作参数是将数组元素的值传递到形参对应的内存空间中,之后操作是对形参对 应空间的数值进行的,故原来的数组内容不变:而数组名作参数是将数组名的值(即数组首地 址)传递到形参对应的单元中,从而形参的值就是原数组的首地址,之后的操作是根据形参的 值即原数组的首地址进行的,从而原数组的内容改变。 exchange(a0],a[1)-- exchang(inti,intj){ float tmp;tmp=i;i=jj=tmp}/*互换的是形参i与j* excange(a)-- excange(int bD)(float tmp; tmp=bO].b[l=tmp;}/*b=a均为原数组首址* 813’、递推法求勒让德多项式值 #include<stdio. h Int n, I; float x,y,yl, y2 anf(%f%d”,&f&n)/*注意数据类型与格式控制符一致,比如读入实数用%f°/ if(n==0y=1; else if(n==1)y=x: el yl=l; y2=x 应yl=xy2=1;*/ for(i=2; i<=n; i++) y=(2*n-1)*xy1-(n-1)*y2)h;/*应y=(2*i-1)x-y1-(i-1)*y2yiv yl=y2 printf("the result is %fny) /+intn; float x; int p[n]or(i=2;<mn;i+)p[i]=pi-1]+p[i-2]x;因数组名大小必须为常数,故错误* /*intn; float x;intp(n,x),for(i=2;K<n;i++)(n,x=p(n-1x)+pn-2,x)*x:因intp(nx)既非定义变量(不 符合变量命名规则),也非定义函数(函数的形参应指定类型),且赋值语句左侧既非变量,也 非数组名,故严重错误* 递归法自己想!可参考下例类似得到。 817递归法将一个整数以字符形式输出。如483,先用 butchart(输出字符4后 putchar(8)最后
否则,如只写 judge(str[i])则此次函数调用毫无意义,因返回值未被利用;有时不必如此,如子 函数返回值类型为空时,此时调用语句可直接写 trans(str),如输出欢迎界面的子函数,只需输出 一个界面即可,无需返回值;再如数组名作函数参数时,因主调函数和被调函数中的数组是同 一个数组,在子函数中对数组加以改变,原函数中的数组也相应改变,故此时无返回原数组也 发生了改变! (9)求最长单词并输出一题提示:设一个标记变量 flag,用 flag=0 或 1 代表前一个字符是否 空格,当且仅当前一个字符是空格,且当且字符是字母代表单词开始。当前一个字符不是字母, 而当且字符不是字母是单词结束。 第二次作业说明 一、递归法 N-S 图画法,如求 n!对应的 N-S 图如下: 主函数:输入 n,调用递归函数 f 求 n!: /*递归法求阶乘子函数*/ int f(int m) 或 二、 说明:数组元素作参数是将数组元素的值传递到形参对应的内存空间中,之后操作是对形参对 应空间的数值进行的,故原来的数组内容不变;而数组名作参数是将数组名的值(即数组首地 址)传递到形参对应的单元中,从而形参的值就是原数组的首地址,之后的操作是根据形参的 值即原数组的首地址进行的,从而原数组的内容改变。 exchange(a[0],a[1]) ---> exchang(int i,int j){float tmp;tmp=i;i=j;j=tmp}/*互换的是形参 i 与 j*/ excange(a) ---> excange(int b[]){float tmp;tmp=b[0];b[1]=tmp;}/*b=a 均为原数组首址*/ 8.13’、递推法求勒让德多项式值 #include void main() { int n,i; float x,y,y1,y2; printf(“input x & n\n”); scanf(“%f %d”,&f,&n) /*注意数据类型与格式控制符一致,比如读入实数用%f*/ if(n= =0)y=1; else if(n= =1)y=x; else { y1=1;y2=x; /*应 y1=x;y2=1;*/ for(i=2;i<=n;i++) { y=((2*n-1)*x-y1-(n-1)*y2)/n; /*应 y=((2*i-1)*x-y1-(i-1)*y2)/i*/ y1=y2; y2=y; } } printf(“the result is %f\n”,y); } /*int n;float x;int p[n];for(i=2;i<n;i++)p[i]=p[i-1]+p[i-2]*x;因数组名大小必须为常数,故错误*/ /* int n;float x;int p(n,x); for(i=2;i<n;i++)p(n,x)=p(n-1,x)+p(n-2,x)*x;因 int p(n,x)既非定义变量(不 符合变量命名规则),也非定义函数(函数的形参应指定类型),且赋值语句左侧既非变量,也 非数组名,故严重错误*/ 递归法自己想!可参考下例类似得到。 8.17 递归法将一个整数以字符形式输出。如 483,先用 putchar()输出字符 4,后 putchar(‘8’),最后 输入 n p=f (n) 输出 p m= =1 Y N return(1) return(f(n-1)) m= =1 Y N x=1 X=f(m-1) return(x)
putchar(3) 递归求解思路如下,构造递归函数 void convert(intn);用以将n转化为字符串输出: (1)当n为个位数即n10==0时直接输出该数字对应的字符即可 if(n/10==0) putchar(n+0);/*如 butchart(8输出ASCⅡ码为8的字符,而 putchan(8)输出数字字符8, 显然8的 ASCII码值等于0的ASCI码加8*/ (2)降阶:假设 convert(n/10)能正确将n10转化并输出,则对于n分两步: 先用 convert(n/10)将n/10转化并输出,之后输出n%10对应的字符。 #include void maino void convert( int n),/函数声明,此时函数返回值类型和形参类型不可省,但形参变量名可省* printI("input n.n”); scanf("%d", &n) convert(n); /*函数调用,此时不可有函数返回值类型和形参类型,写上实参即可* void convert(int n)/*函数定义,此时函数返回值类型、形参类型和形参变量名均不可省* if(n/10==0) putchar(n%10+0);/" putchar(8)输出ASCI码为8的字符,而 putcha(8)输出数字字符8, 显然8的 ASCII码值等于0的ASCI码加8*/ har(n%10+0) 输入123,程序执行过程如下,注意箭头方向与缩进意义 convert(123)/*第一次调用函数时形参为123*/ >n=123;i=12; convert(12),/*第二次调用时形参为12.,返回后执行 putchar(123%10+0)* >n=12;i=l; convert);/第三次调用时形参为1,返回后执行 putchai(12%10+0)* >n=1;=0; putchar(1%10+0);*第三次调用结束* putchar(12%10+0)x *输入矩阵子函数* void inputmatrix( float a[ I COLUM)/只有第一维大小可省略,形参名可改* printf("input the matrix: In") for(i=0 i<ROWNUM: 1++) for(=0: j<COLNUM: j++) scanf("%f, &ajD; /*foat型变量在输入输出时不可用%d,int型不可用%f*/ *输出矩阵子函数* void outputmatrix(float aDICOLNUMD) int 1,J printf("the matrix is: In"); for(i=0 i<ROWNUM; i++) for(=0; j<COLNUM j++)printf("%5.2f " a[[: printf("n") /寻找非零行函数若a[订为0,则找其正下方非零元素所在行找不到返回-1,否则返回行号* nt findnzero(float a[[ COLNUM,inti)/函数起名也要见名知义 int j result=-1 for(i+l:j<ROWNUM: j++)
putchar(‘3’) 递归求解思路如下,构造递归函数 void convert(int n);用以将 n 转化为字符串输出: (1) 当 n 为个位数即 n/10==0 时直接输出该数字对应的字符即可 if(n/10==0) putchar(n+'0'); /*如 putchar(8)输出 ASCII 码为 8 的字符,而 putchar(‘8’)输出数字字符 8, 显然 8 的 ASCII 码值等于 0 的 ASCII 码加 8*/ (2) 降阶:假设 convert(n/10)能正确将 n/10 转化并输出,则对于 n 分两步: 先用 convert(n/10)将 n/10 转化并输出,之后输出 n%10 对应的字符。 #include void main() { int n; void convert(int n); /*函数声明,此时函数返回值类型和形参类型不可省,但形参变量名可省*/ printf(“input n:\n”); scanf(“%d”,&n); convert(n); /*函数调用,此时不可有函数返回值类型和形参类型,写上实参即可*/ } void convert(int n) /*函数定义,此时函数返回值类型、形参类型和形参变量名均不可省*/ { int i; if(n/10==0) putchar(n%10+'0'); /*putchar(8)输出ASCII 码为8的字符,而putchar(‘8’)输出数字字符8, 显然 8 的 ASCII 码值等于 0 的 ASCII 码加 8*/ else { convert(n/10); putchar(n%10+'0'); } 输入 123,程序执行过程如下,注意箭头方向与缩进意义 convert(123) /*第一次调用函数时形参为 123*/ -->n=123;i=12;convert(12); /*第二次调用时形参为 12,返回后执行 putchar(123%10+’0’)*/ -->n=12; i=1; convert(1); /*第三次调用时形参为 1,返回后执行 putchar(12%10+’0’)*/ -->n=1;i=0;putchar(1%10+'0'); /*第三次调用结束*/ putchar(12%10+'0'); /*输入矩阵子函数*/ void inputmatrix(float a[][COLNUM]) /*只有第一维大小可省略,形参名可改*/ { int i,j; printf("input the matrix:\n"); for(i=0;i<ROWNUM;i++) for(j=0;j<COLNUM;j++) scanf("%f",&a[i][j]); /*float 型变量在输入输出时不可用%d,int 型不可用%f*/ } /*输出矩阵子函数*/ void outputmatrix(float a[][COLNUM]) { int i,j; printf("the matrix is:\n"); for(i=0;i<ROWNUM;i++) { for(j=0;j<COLNUM;j++)printf("%5.2f ",a[i][j]); printf("\n"); } } /*寻找非零行函数,若 a[i][i]为 0,则找其正下方非零元素所在行,找不到返回-1,否则返回行号*/ int findnzero(float a[][COLNUM],int i) /*函数起名也要见名知义*/ { int j,result=-1; for(j=i+1;j<ROWNUM;j++)
if(an0!=0)result=j; break; /*两行互换子函数 void exchange(float a[ICOLNUMI, int i, int j) int k; float tmp; for(k=0; k<COLNUM; k++)(tmp=ai(k]; a[il(k]=allk] anl(k]=tmp; j /消元子函数行加上j行的k倍,结果放回i行* drow( float a[[ COLNUM, Int 1, Int J, float k)/*注意形参的类型* for(tmp=0; tmp<COLNUM; tmp++atmp=ail tmpl+k*aljilltmpl /* Gauss消去法化阶梯形* int gauss( float a[ICOLNUMD flag sign=l for(i=0: i<ROWNUM-1; 1++) if(aJ1==0) flag=findnzero(a, 1) if(flag==-1)continue *若当前列剩余元素均零则重新开始循环,处理下一行* else exchange(a, i, flag) sign*=-1; i for(=计+1j< ROWNUM J++) addrow(a i, i,-aljl[iya[);/*逐行进行消元*/ return(sign); void maino float a( ROWNUMIICOLNUM] inputmatrix(a gauss(a)
if(a[j][i]!=0){result=j;break;} return(result); } /*两行互换子函数*/ void exchange(float a[][COLNUM],int i,int j) { int k;float tmp; for(k=0;k<COLNUM;k++){tmp=a[i][k];a[i][k]=a[j][k];a[j][k]=tmp;} } /*消元子函数,i 行加上 j 行的 k 倍,结果放回 i 行*/ addrow(float a[][COLNUM],int i,int j,float k) /*注意形参的类型*/ {int tmp; for(tmp=0;tmp<COLNUM;tmp++)a[i][tmp]=a[i][tmp]+k*a[j][tmp]; } /*Gauss 消去法化阶梯形*/ int gauss(float a[][COLNUM]) { int i,j,flag,sign=1; for(i=0;i<ROWNUM-1;i++) { if(a[i][i]= =0) { flag=findnzero(a,i); if(flag= =-1)continue; /*若当前列剩余元素均零则重新开始循环, 处理下一行*/ else {exchange(a,i,flag);sign*=-1;} } for(j=i+1;j<ROWNUM;j++)addrow(a,j,i,-a[j][i]/a[i][i]); /*逐行进行消元*/ } return(sign); } void main() { float a[ROWNUM][COLNUM]; inputmatrix(a); gauss(a); outputmatrix(a); }