6.2 填充题 1.静态型内部变量的作用域是___________。 【解】静态存储类型的主要特性是永久性和专用性。静态局部变量提供永久存储,但因它是局部变量,也得遵守局部变量的作用域规则,是定义它的函数或复合语句。
2.函数中的形参和调用时的实参都是数组名时,传递方式为______;都是变量时,传递方式为_____________。 【解】在C语言中,实参向形参传递方式只有值传递,但传递的内容可能是非指针类型的值,如基本类型值,或结构类型值,也可以是指针类型值。通常传递指针类型值特称为传地址方式。其中实参向指针形参传递数组名,就是一种传地址方式。若形参不是指针类型的,形参是一般的变量,实参可以是变量或表达式,就是值传递方式。
3.函数的形式参数的作用域为_____,全局的外部变量和函数体内定义的局部变量重名时,________变量优先。 【解】函数将它的形参当作它的局部变量,所以函数形参的作用城为定义它的函数。当函数的形参或函数内的局部变量与函数外的全局变量同名时,函数的局部变量优先。
4.若自定义函数要求返回一个值,则应在该函数体中有一条________语句,若自定义函数要求不返回一个值,则应在该函数说明时加一个类型符____________。 【解】苦自定义的函数有返回值,则函数返回时应执行带表达式的return语句返回,该表达式的值将作为函数调用的结果。为了强调函数是一个不返回值的函数,应在该函数说明时,加上一个void类型说明符。
5.若给fun函数的形参s传送字符串:"ㄩㄩ 6354abcc"(其中ㄩ表示空格字符),则函数的返回值是__________。 # include long fun(char s[]) { long n;int sign; for(; isspace(*s); s++); sign=(*s==’-’ )?-1:l; if(*s==’+’ ||*s==’-’) s++; for(n=0; isdigit(*s); s++) n=10*n+(*s-’0’); return sign *n; } 【解】函数fun的第一个for循环跳过字符串的前导空白符,接着分析第一个非空白符是否是负号,若是置变量sign为-1;否则,置变量sign为1。接着的if语句在第一个非空白字符是负号或正号时,跳过该字符。以后的for循环将后面的数字符当作十进制数的各位数字译出一个长整数n。遇字符a时,结束译数循环。最后,函数返回sign与n的乘积。所以若调用函数时提供的实参是"ㄩㄩ6354abc",函数返回值是整数6354。
6.下面函数要求计算两个整数X、y之和,并通过形参Z传回该和值,请填空。 void add(int x,int y,________z) {_________=x+ y; return;} 【解】函数希望通过形参z传送结果,形参z必须是指针类型的,由于返回整型结果,所以z的说明是int *z。函数返回前必须先把结果通过形参z间接引用(写成* z)传回。7.以下函数用来在w数组中插入x。在n所指向的存储单元中存放着w数组中的字符个数。数组W中的字符已按从小到大的顺序排列,插入后数组W中的字符仍有序。请填空。 void fun(char *w,char x, int *n) { int i, p; p=0; w[*n]=x; whlie( x>w[p] ) p++; for(i=* n; i>p;i--) w[i]=_____________; w[p] = x; ++ *n; } 【解】在用数组实现的有序序列中插入内容,必须先寻找插入位置。插入位置找到后,需将插入位置之后的元素向后移动一个位置,留出插入点。最后,将元素插入,并增加序列的元素个数。函数为了简化寻找插入位置循环的循环条件,预先在序列的最后置人插入值。插入位置之后的元素向后移动一个位置必须从最后一个元素开始往前逆序移动,是将前一个元素向后移,所以在空框处应填入w[i-l] 。
8.函数my_cmp()的功能是比较字符串s和t的大小,当S等于t时返回0,否则返回s和t的第一个不同字符的ASCII码差值,即s>t时返回正值,当s my_cmp( char *s, char * t) {while(*s==* t) { if(*s==’\0’) return 0 ; ++s;++t; } return____________; } 【解】两字符串大小比较必须从它们的首字符开始,在对应字将相等情况下循环,直至不相等结束。相等时,老字符率已到了字符串的结束标记符,则两字符率相同,函数退回0值;如还有后继字符,则准备比较下一对字符。对应字符不相同,循环结束。循环结束时,就以两个当前字符的差返回。所以在空框处应填入*s-*t,保证在s>t时返回正值,当s 6.3 程序分析题 1.阅读函数,写出函数的主要功能: ch(int *p1,int *p2) { int p; if(*pl>*p2) { p=* pl;*pl=*p2;* p2=p; } } 【解】函数办有两个指针形参p1和p2,函数体通过*pl和*p2间接引用它们所指变量。当pl所指变量的位大于p2所指变量的值时,交换两形参所指变量的值。所以函数的功能当形参1所指变量比形参2所指变量的值大时,交换这两个变量的值。调用该函数能保证形参1所指变量的值不大于形参2所指变量的值。
2.阅读函数,写出函数的主要功能: float av(a,n) float a[]; int n; { int i; float s; for(i=0,s= 0;i return s/n; } 【解】函数有一个数组形参a和一个整型形参n。函数首先用循环求数组a的前n个元素和,然后将和除以n。即求数组元素的平均值。
3.阅读下面程序,写出运算结果。 unsigned fun6( unsigned num) { unsigned k=l; do { k*= num;num/=10;} while(n) ; return k; } main() { unsigned n=26; printf("%d\n", fun6(n)); } 【解】函数有一个形参num,循环前变量 k置 1,循环中,表达式num是取num的个位,将num的个位值累乘于k中,然后num除以10。循环直至num为0结束,这是逐一求出num十进制表示的各位数字,并累乘于变量k的循环。函数最后返回k。函数fun6的功能是求整数的各位十进数字积。所以程序输出12。 6.4 程序设计题 1.编一个名为root的函数,求方程ax*x + bx + c=0的b*b-4ac,并作为函数的返回值。其中的a、b、c作为函数的形式参数。 【解】该函数应设3个形参,分别表示一元二次方程的三个系数。函数按公式求出结果返回即可: double root(double a,double b,double c) { return b*b+4.0*a*c; }
2.编一个函数,若参数y为闰年,则返回1;否则返回0。 【解】由每四年一个闰年,但每100年少一个闰年,每400年又增加一个闰年的约定。记年份为y,则y年是闰年的条件是: (y能被4整除,但不能被100整除)或(y能被400整除) 用逻辑表达式可描述如下: (y%4==0 && y0) ||y@0==0 写成函数为: int isLeap(int y) { return( y% 4==0 && y% 100) || y@0== 0; }
3.编一个无返回值,名为root2的函数,要求如下: 形式参数: a,b,c单精度实型,root单精度实型数组名。 功能:计算ax*x +bx+c=0的两个实根(设b*b-4ac> 0)存入数组root[2]中。 【解】函数根据形参。a,b,c的值,首先计算d=b*b-4*a*c。考虑到实数运算时的计算误差,两个几乎相等的数相减有效位数也几乎全部丢失的情况,应先求出绝对值大的根,然后利用报与系数之间的关系,再求绝对值小的根。函数定义如下: void root2( float a,float b,float c, float root[]) { float re,im,d=b*b-4.0*a*c;/*求判别式*/ re=-b/(2.0*); if(d>=0.0) { /*有两个实根,先求绝对值大的根*/ im=(float)sqrt((double)d)/(2.0*a) ; root[0] =re+(b<0.0? im:-im); root[1]=c/(a*root[0]); } }
|