C语言典例解析

发布时间 : 星期二 文章C语言典例解析更新完毕开始阅读

已知某数列的前两项为2和3,其后继项根据当前最后两项的乘积按下列规则生成; (1)若乘积为一位数,则该乘积即为数列的后继项;

(2)若乘积为二位数,则该乘积的十位数字和个位数字依次作为数列的两个后继项。 本程序输出该数列的前n 项以及它们的和。其中,函数sum(n,pa)返回数列的前n项之和,并将生成的前n项存放于首指针为pa的数组中。程序中规定输入的n 值必须大于2 并且不超过给定的常数值MAXNUM。

例如:若输入n值为10,则程序输出如下内容: sum(10)=44

2 3 6 1 8 8 6 4 2 4 〔程序〕

# include # define MAXNUM 100

int sum(int n,int *pa) { int count,total,temp; *pa=2;

___(1)___ =3; total=5;count=2; while(count++

{ temp=*(pa-1)* *pa; if(temp<10) { total+=temp; *(++pa)=temp; } else

{ ___(2)___ =temp/10; total+=*pa; if(count

___(3)___ =temp; total+=*pa; } } }

___(4)___ ; }

main()

{ int n,*p,*q,num[MAXNUM];

do { printf(\(2

} while(___(5)___ );

printf(\(%d)=%d \(n,num)); for(p=num,q= ___(6)___ ;p

printf(\); } 答案:

(1)*++pa (2)*++pa (3)*pa

(4)return(total) (5)n<3 ││ n>MAXNUM (6)p+n 或num+n 或&num[n]

分析:

函数int sum(int n,int *pa)返回按试题要求构造的数列前n项之和,并将生成的前n项存放于首指针为pa的数组中。根据试题构造数列的规则,数列的前两项为2和3。(1)空所在的语句将数列第二项值3存入首指针为pa的数组中。因此,可用语句*(pa+1)=3或*++pa=3实现。由于计算数列后继项的语句为*(pa-1)**pa,因此,(1)空处的语句只能为*++pa=3。在函数中,变量count用于存放目前已经计算出的数列的项数,变量total用于存放目前已经计算出的数列中各项之和。,后继项根据当前最后二项的乘积按下列规则生成: (1)若乘积为一位数,则该乘积即为数列的后继项;

(2)若乘积为二位数,则该乘积的十位数字和个位数字依次作为数列的两个后继项。 在函数中,语句temp=*(pa-1)* *pa计算出最后二项的乘积并存于temp,若temp小于10,则该项就是后继项。若temp大于或等于10,则temp的十位数字和个位数字依次作为数列的两个后继项,需将temp的十位数字和个位数字分别保存到数组中并加入到和total值中。(2)空所在语句是计算出temp的十位数字,并将该数字保存到数组中。又由于pa是指向数组中最后一个保存的数字,因此,需先将指针pa右移,再保存数字。即(2)空答案为*++pa。同理,(3)空所在语句是计算出temp的个位数字,并将该数字保存到数组中。又由于在(3)空所在的语句前已经有pa++语句使指针pa右移。因此,(3)空的答案为*pa。由于函数的返回值为数列的前n项之和,当执行完循环语句while(count++

程序中规定输入的n 值必须大于2 并且不超过给定的常数值MAXNUM。因此,当输入的n值小于3或大于给定的常数值MAXNUM时,需重新输入。因此,(5)空的答案为n<3 ││ n>MAXNUM。(6)空所在的循环语句是输出数列的前n项值,由于循环变量采用了指针p,因此当指针p的值小于数组中第n+1个元素的地址时,则继续循环输出。因此,(6)空的答案为p+n或num+n 或&num[n]。

15.递推实例2

数列 A={1,1,3,7,17,41,??.}有以下性质: a0=a1=1

ai=ai-2+2ai-1 (i>=2)

对于给定的n,数列Xn有n 个元素,各元素的值为 ai/ai+1(i=0,1, ?n-1)

且按升序排列,其中Xn的各元素值以分数形式表示。

函数makex()首先在枚举数列A的元素时,生成Xn的元素,然后对Xn的元素进行排序,最后顺序输出排序后的Xn的各元素。例如,当n=5时,X5={1/3,7/17,17/41,3/7,1/1}。 〔程序〕

# include # include

void sort(int n, struct fact *p); void makex(int n); struct fact{ long m; long n; };

int test_list[ ]={4,5,8}; void main() { int i;

for(i=0;i<3;i++) makex(test_list[i]); }

void makex(int n) { int i; long a,b,c;

struct fact *x,* y;

x=(struct fact *)malloc(sizeof(struct fact)*n); x->m=1;x->n=1; a=1;b=1;

for(i=2;i<=n;i++) { c=a+2*b;a=b;b=c;

___(1)___ =a; ___(2)___ =b; }

sort(n,x);

printf(\->m,x->n}; for(___(3)___;y++)

printf(\->m,y->n); printf(\);free(x); }

void sort(int n, struct fact *p) { int b; long s,t,u,v; struct fact *q,* end;

end= ___(4)___ ;b=1; while(b) { b=0;

for(q=p;qm; t=q->n;

u=(q+1)->m;v=(q+1)->n; if(s*v>t*u)

{(q+1)->m=s;(q+1)->n=t; q->m =u;q->n =v; ___(5)___ ; } }

___(6)___ ; } } 答案: (1)(x+i-1)->m (2)(x+i-1)->n (3)y=x+1;y

(6)end-- 或end=end-1或--end

分析:

函数void makex(int n)首先按递推公式ai=ai-2+2ai-1计算出数列A中的元素,并通过计算出的元素生成Xn的元素,然后对Xn的元素进行排序,最后顺序输出排序后的Xn的各元素。在函数中计算数列元素时,首先将数列的初始值1、1分别赋于变量a和b,并存入x所指的存储单元中的第一个元素。接着通过循环语句for(i=2;i<=n;i++){?}依次计算出数列中的后继元素,并将后继元素与该元素的前一个元素组成新的分数存于x所指的存储单元中的相应位置。通过循环方法,并按递推公式ai=ai-2+2ai-1计算后继项:设前两项的值为a和b,则当前项的值c=a+2*b。由于在下一次循环中还是通过表达式c=a+2*b来计算下一项的值,因此,在计算出当前项c之后,a、b的值在数列A中应右移一个位置,可用语句a=b和b=c来实现。根据题意,每计算出数列A中的一个元素,就可以与该元素的前一个元素组成一个新的分数存于x所指的存储单元中。新计算出的元素为分数的分子,前一个元素为分数的分母。当计算出数列中的第i个元素与数列的第i-1个元素组成的分数(即ai-1/ai)为x中的第i个元素,需存放在x所指的第i个存储单元中(该存储单元的地址为x+i-1)。从函数中的输出语句可知,在元素xi中,m存放分子,n存放分母。因此,(1)空的答案为(x+i-1)->m,(2)空的答案为(x+i-1)->n。函数中通过调用函数sort()实现了对x中的n个分数进行排序,排序后输出排好序的数列x。(3)空所在的循环语句实现了输出数列x中的第二个至第n个分数,因此,循环变量y的初始值为x+1,继续循环的条件为y

函数void sort(int n, struct fact *p)的功能是对形式参数x所指的n个存储单元中的分数按从小到大的顺序排序。在函数中的排序采用了改进的冒泡排序方法--即每趟排序中不出现交换就结束的冒泡排序。在函数中,变量end存放了每趟比较中的最后一对元素的位置。在第一趟冒泡排序中,最后一对比较的元素位置为p+n-2与p+n-1,又由于内循环中结束循条件为q

联系合同范文客服:xxxxx#qq.com(#替换为@)