admin管理员组文章数量:1576977
2023年12月26日发(作者:)
习 题 9
一.选择题
1. A 2. A 3. A 4. A 5.B 6.C
二 编程题
9.2 编写一函数,判断N×N矩阵是否为上三角阵。上三角阵是指不含主对角线,下半三角都是0的矩阵。
#include
int fun(int x[][3],int n){
int flag=1,i,j;
for(i=1;i for(j=0;j if(x[i][j]!=0){ flag=0;break; } return flag; } void main() { int a[3][3]={{1,4,5},{0,2,6},{0,0,3}}; int result=fun(a,3); if(result==1) printf("此矩阵是上三角矩阵!n"); else printf("此矩阵不是上三角矩阵!n"); } 9.3 有一个字符串,包含n个字符,将字符串从第i个字符到第j个字符间的字符逆置。 程序代码: #include #include void invertsub(char *str,int i,int j){ char *p,*q,c; int n=0; p=q=str; if(str==NULL) printf("str is NULL!n"); else if(i<=0||j>strlen(str)) printf("i and j value error!n"); else { while(*p!='0'&&n!=i-1) { p++;n++; } q=p; while(*q!='0'&&n!=j-1){ q++;n++; } while(p c=*p; *p++=*q; *q--=c; } } } void main(){ char str[]="abcdefg"; printf("%sn",str); invertsub(str,2,5); printf("%sn",str); } 9.4 题目:有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数 .程序源代码: main() { int number[20],n,m,i; printf("the total numbers is:"); scanf("%d",&n); printf("back m:"); scanf("%d",&m); for(i=0;i scanf("%d,",&number[i]); scanf("%d",&number[n-1]); move(number,n,m); for(i=0;i printf("%d,",number[i]); printf("%d",number[n-1]); } move(array,n,m) int n,m,array[20]; { int *p,array_end; array_end=*(array+n-1); for(p=array+n-1;p>array;p--) *p=*(p-1); *array=array_end; m--; if(m>0) move(array,n,m); } 9.5 输入n个整数,将最小数与第一个数对换,把最大数与最后一个数对换 程序源代码: main() { int number[10]; input(number); max_min(number); output(number); } input(number) int number[10]; {int i; for(i=0;i<9;i++) scanf("%d,",&number[i]); scanf("%d",&number[9]); } max_min(array) int array[10]; {int *max,*min,k,l; int *p,*arr_end; arr_end=array+10; max=min=array; for(p=array+1;p if(*p>*max) max=p; else if(*p<*min) min=p; k=*max; l=*min; *p=array[0];array[0]=l;l=*p; *p=array[9];array[9]=k;k=*p; return; } output(array) int array[10]; { int *p; for(p=array;p printf("%d,",*p); printf("%dn",array[9]); } 9.6 输入n个字符串,按由小到大顺序输出。 程序源代码: main() { char *str1[20],*str2[20],*str3[20]; char swap(); printf("please input three stringsn"); 2scanf("%s",str1); scanf("%s",str2); scanf("%s",str3); if(strcmp(str1,str2)>0) swap(str1,str2); if(strcmp(str1,str3)>0) swap(str1,str3); if(strcmp(str2,str3)>0) swap(str2,str3); printf("after being sortedn"); printf("%sn%sn%sn",str1,str2,str3); } char swap(p1,p2) char *p1,*p2; { char *p[20]; strcpy(p,p1);strcpy(p1,p2);strcpy(p2,p); } 9.7 写一函数,功能是交换两个实数变量的值。 void swap(float * x, float * y); main() { float a, b, *p1, *p2; a=10; b=20; p1=&a; p2=&b; printf("a=%f, b=%fn", a, b); swap(p1, p2); printf("a=%f, b=%fn", a, b); /* 或printf(″%d %d″, *p1, *p2) */ } void swap(float *pa, float *pb) { float temp; temp=*pa; *pa=*pb; *pb=temp; } 9. 10 写一个函数,求一个字符串的长度。 程序源代码: main() { int len; char *str[20]; printf("please input a string:n"); scanf("%s",str); len=length(str); printf("the string has %d characters.",len); } length(p) char *p; { int n; n=0; while(*p!='0') { n++; p++; } return n; } 9.11 约瑟夫环问题:n个人围成一圈,从第一个人开始报数,凡报到3的人退出,问最后剩下的是第几号。 程序代码: #define nmax 50 main() { int i,k,m,n,num[nmax],*p; printf("please input the total of numbers:"); scanf("%d",&n); p=num; for(i=0;i *(p+i)=i+1; 3 i=0; k=0; m=0; while(m { if(*(p+i)!=0) k++; if(k==3) { *(p+i)=0; k=0; m++; } i++; if(i==n) i=0; } while(*p==0) p++; printf("%d is leftn",*p); } 9.12 # include "stdio.h" # define NULL 0 # define LEN sizeof(struct student)/*LEN表示结构体student的长度*/ struct student { long num; int score; struct student *next;}; /*student成员中的next仍为student结构体类型,链表必用此种结构*/ struct student listA,listB; /*listA,listB皆为student结构体类型*/ int n,sum=0; void print(head) /*输出函数*/ struct student *head; { struct student *p; printf("n sum %d record ,they are :n",sum); if (pb1->num p=head; { if(ah==pa1)ah=pb1; /*/*从表头开始*/ 如果现在ah指向第一个链表的某结点, 则让ah指向第二个链表的当前结点,乃因第二个链表 if(p!=NULL) do /*未到结尾时*/ { printf("%ld %dn",p->num,p->score); /*输出学号和成绩*/ p=p->next;} /*指针前进*/ while(p!=NULL);} struct student *insert(ah,bh) /*定义插入函数*/ struct student *ah,*bh; { struct student *pa1,*pa2,*pb1,*pb2; /*这四个指针皆为student结构体类型*/ pa2=pa1=ah; /*两个指针指向第一链表的表头*/ pb2=pb1=bh; /*两个指针指向第二链表的表头*/ do { while((pb1->num>pa1->num)&&(pa1->next!=NULL)) /*注意是按学号链接.当第二个链表的学号大于第一个链表的学号而且未到第一个链表结尾时*/ { pa2=pa1;pa1=pa1->next;} /*用pa2记下第一个链表的当前位置,pa1前进到下一个结点.到此已经脱离循环*/ 4 的学号比第一个链表的学号小.注意ah为目标链表*/ else pa2->next=pb1; /*否则,第二个链表pa2指针指向第二个链表的当前位置*/ pb1=pb1->next;pb2->next=pa1; /*做完上面的事情,两指针同时前进到下一个结点*/ pa2=pb2;pb2=pb1;}} /*pa2指向第二个链表的当前位置,pb2 指向第二个链表的当前位置*/ while ((pa1->next!=NULL)||(pa1==NULL&&pb1!=NULL)); /*当第一个链表未到末尾或者第一个链表结束而第二个链表未结束 时,便重复做上面的事情*/ if((pb1->num>pa1->num)&&(pa1->next==NULL)) /*脱离循环时如果是第一个链表结束而且第二个链表之序号大于第一个 链表之序号则把pa1之next 域指向第二个链表的当前位置*/ pa1->next=pb1; return(ah); } /*返回目标链表的头地址*/ struct student *creat() /*定义建立链表函数*/ { struct student *p1,*p2,*head; /*此三个指针皆为student结构体类型*/ n=0; /*计数器n赋初值为0*/ p1=p2=(struct student *)malloc(LEN); /*为结构体分配地址,p1,p2都指向这个地址*/ printf("input sno score:n"); printf(" input 0 end."); scanf("%ld,%d",&p1->num,&p1->score); /*输入学号和成绩*/ head=NULL; /*表头先置为空指针*/ while (p1->num!=0) /*当输入的学号不为0时*/ { n=n+1; /*计数器增值1*/ if(n==1)head=p1; /*如果是第生个结点,head指向第一个结点*/ else p2->next=p1; /*如果不是第一个结点,链结到p2中,p2是建立的链表*/ p2=p1; /*指针p2前进*/ p1=(struct student *)malloc(LEN); /*再分配地址*/ scanf("%ld,%d",&p1->num,&p1->score);} /*再输入学号及成绩*/ p2->next=NULL; /*当脱离循环时,链表已经建立完毕.勿忘给表尾一个空指针*/ return(head);} /*返回表头地址*/ main(){ 5struct student *ahead,*bhead,*abh; /*三个变量皆为结构体student类型*/ ahead=creat(); print(ahead); /*调用建立链表函数建立链表llistA,把返回地址赋给指针ahead*/ sum=n; /*n为链表结点数*/ bhead=creat(); print(bhead); /*调用建立链表函数建立链表llistB,把返回地址赋给指针bhead*/ sum=sum+n; /*sum为两个链表的结点总数*/ abh=insert(ahead,bhead); /*调用插入函数连结两个链表,把表头地址赋给abh*/ print(abh);} /*打印连接的结果*/ 9.1 写一个函数,将一个3行3列矩阵转置。 main()/*将一个3行3列矩阵转置*/ { int a[3][3],*p,i; printf("input 3*3 ju zhen:n"); for (i=0;i<3;i++)/*一行一行的输入*/ scanf("%d %d %d",&a[i][0],&a[i][1],&a[i][2]); p=&a[0][0];/*p指向二维数组首地址*/ move(p);/*调用转置函数进行转置*/ printf("zhuan zhi hou juzhen wei:n"); for (i=0;i<3;i++)/*一行一行的输出*/ printf("%d %d %dn",a[i][0],a[i][1],a[i][2]);} move(pointer)/*自己定义矩阵转置函数*/ int *pointer; { int i,j,t; for(i=0;i<3;i++) for (j=i;j<3;j++) {t=*(pointer+3*i+j);/**(pointer+3*i+j)乃a[i][j]*/ *(pointer+3*i+j)=*(pointer+3*j+i);/**(pointer+3*j+i);乃a[j][i]*/ *(pointer+3*j+i)=t;}}/*此三句实现a[i][j]与a[j][i]互换*/ 9.13 运行结果: main() { int len=1,i; struct line *p1,*head,*new,*newhead; /*此行指针皆为line类型*/ p1=head=(struct line *)malloc(sizeof(struct line)); /*各指针都指向系统分配的内存地址*/ p1->num=-1; head->next=NULL; while (p1->num!=0)/*当输入的不是0时*/ { p1=(struct line *)malloc(sizeof(struct line));/*再分配地址*/ printf("p->num?:"); scanf("%d",&p1->num);/*再输入结点值*/ p1->next=head; head->next=p1; len++;}} 9.14 将n个数按输入时的顺序逆序排列。 程序代码如下: /*结点数自增值*/ # define NULL 0 p1=head->next;/*指针指向表头,准备输出*/ struct line printf(" output link n "); { int num; do { struct line *next;}/*定义结构体类型line,此中next是line类型的指针. 处理链 表必用此种结构*/ printf("%4d",p1->num);/*输出结点值*/ 6 if(p1->next!=NULL)p1=p1->next;}/*如果未到表尾指针前进到下一个结点*/ while(p1!=NULL); /*循环终止条件*/ } 9.17 有一个班4个学生,5门课,求: ① 第一门课的平均分; ② 找出有两科以上不及格的学生; ③ 找出平均成绩在90分以上者或全部课程成绩在85分以上者。 有10个学生,每个学生包括学号、姓名和三门课的成绩,要求打印出三门课崐总平均成绩以及最高分的学生数据。 /*输入10个学生数据,计算平均分*/ struct student { char num[6]; char name[8]; int score[4]; float avr;}stu[10];/*定义stu[10]为student型结构体数组*/ main() { int i,j,max,maxi,sum; float average; /*输入*/ for (i=0;i<10;i++) { printf("n请输入第%d个学生的成绩:n",i+1); printf("学号: "); scanf("%s",stu[i].num); 7printf("姓名: "); scanf("%s",stu[i].name); for(j=0;j<3;j++) { printf("成绩 %d.",j+1); scanf("%d",&stu[i].score[j]);}}/*输入数据*/ /*计算*/ average=0; max=0; maxi=0; for(i=0;i<10;i++) { sum=0; for(j=0;j<3;j++) sum+=stu[i].score[j];/*累加每个人的分数*/ stu[i].avr=sum/3.0;/*总分被3除得平均分*/ average+=stu[i].avr;/*累加总平均成绩*/ if(sum>max){max=sum;maxi=i;}}/* 如果这个人的总成绩大于当前最高成绩则此成 绩替换掉当前最高成绩*/ average/=10;/*总平均分被10除得平均分*/ /*打印*/ printf(" 学号 姓名 成绩1 成绩2 成绩3 平均分n"); for(i=0;i<10;i++) { printf("%8s%10s",stu[i].num,stu[i].name);/*先输出学号,姓名*/ for(j=0;j<3;j++)/*再输出三科成绩*/ printf("%7d",stu[i].score[j]); printf(" %6.2fn",stu[i].avr);}/*输出每个人平均分*/ printf("平均成绩是%5.2fn",average);/*输出总平均成绩*/ printf("最好成绩是学生 %s,总分是 %d.",stu[maxi].name,max);}/*输出最高 分及相应学生姓名*/ 9.19 实现两个字符串的比较。 程序代码如下: int compare(char *s1, char *s2){ int c; while (*s1!='0'||*s2!='0'){ if (*s1<*s2) {c=-1;return c ;} else if (*s1>*s2) {c=1;return c;} else {s1++;s2++;} } if(*s1=='0') if(*s2=='0') c=0; else c=-1; else if(*s2=='0') c=1; return c; } main(){ char *s1,*s2; 8int c; printf("ninput string s1,s2n"); scanf("%s",s1); scanf("%s",s2); c=compare(s1,s2); printf("result is "); if (c>0)printf("s1>s2"); else if (c==0)printf("s1==s2"); else printf("s1 } 9.20 输入一个月份号,输出该月的英文名。 程序代码如下: #include main() {enum month {jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec}; enum month i,; int * j; printf("input month ?n"); scanf("%d",j); switch (j-1) { case jan:printf("%-10s","jan"); break; case feb: printf("%-10s","feb"); break; case mar: printf("%-10s","mar"); break; case apr: printf("%-10s","apr"); break; case may: printf("%-10s","may"); break; case jun: printf("%-10s","jun"); break; case jul: printf("%-10s","jul"); break; case aug: printf("%-10s","aug"); break; case sep: printf("%-10s","sep"); break; case oct: printf("%-10s","oct"); break; case nov: printf("%-10s","nov"); break; case dec: printf("%-10s","dec"); break; default :break;} printf("n"); } 9.21 将空格分开的字符串称为单词。输入多行字符串,直到输入"stop"•单词时才停止。最后输出单词的数量 程序代码如下: #include "stdio.h" main(){ char string[81],*p; int i,num=0,word=0; char c; gets(string); puts(string); 9for(p=string;!(p[0]=='s'&&p[1]=='t'&&p[2]=='o'&&p[3]=='p');p++) if (*p==' ') word=0; else if(word==0) {word=1; num++;}; printf("nthere are %d words n",num); } 9.24指针编写比较两个字符串s和t的函数strcmp(s,t)。要求s 程序代码如下: int compare(char *s, char *t){ int c; while (*s!='0'||*t!='0'){ if (*s<*t) {c=-1;return c ;} else if (*s>*r) {c=1;return c;} else {s++;t++;} } if(*s=='0') if(*t=='0') c=0; else c=-1; else if(*t=='0') c=1; return c; } main(){ char *s,*t; int c; printf("ninput string s,stn"); scanf("%s",s); scanf("%s",t); c=compare(s,t); printf("result is "); if (c>0)printf("s>t"); else if (c==0)printf("s==t"); else printf("s } 9.28一个数的数码倒过来所得到的新数叫原数的反序数。•如果一个数等于它的反序数,则称它为对称数。求不超过1993的最大的二进制的对称数。 程序代码如下: main()/*将n个数按逆序排列*/ { int i,n; int *p,num[20]; printf("input n=?n"); scanf("%d",&n); printf("shu ru %d ge shu n",n); for (i=0;i scanf("%d",&num[i]);/*输入n个数*/ 10p=&num[0];/*指针p指向数组首地址*/ sort(p,n);/*调用逆序函数逆序*/ printf("ni zi shu chun"); for (i=0;i printf("%d,",num[i]);printf("%d",num[n-1]);}/*输出逆序结果*/ sort(p,m)/*逆序排列函数*/ int *p, m; {int i; int change,*p1,*p2; for(i=0;i {p1=p+i;p2=p+m-1-i;/*指针定位*/ change=*p1;/*交换数据*/ *p1=*p2; *p2=change;}} 9.29 找到一个二维数组中的鞍点,即该位置上的元素在该行上最大,该列上最小。也可能没有鞍点。 程序代码如下: # include "stdio.h" # define m 10 # define n 10 /*鞍点是:该位置上的元素在该行最大,在该列上最小*/ main() { int i,j,k,flag1,flag2,a[n][m],max,maxi,maxj; printf("input 10*10 ju zhen ?"); for (i=0;i for (j=0;j scanf("%d",&a[i][j]);/*输入原始矩阵*/ for (i=0;i {for (j=0;j printf("n");}/*输出原始矩阵*/ flag2=0;/*有无鞍点的标志*/ for (i=0;i 数*/for (j=1;j if (a[i][j]>max) {max=a[i][j];maxj=j;}/*逐个和其以后的数(包括自身)比较, 如果某一个数比它大,则将这个数赋与装最大数的变量max,同时标记这个数所在的 列为maxj=*/ for (k=0,flag1=1;k if(max>a[k][maxj]) flag1=0;/*如果这个最大数和它所在列的所有其它元素比较 有某一个元素比max小,则flag1置为0,说明不是鞍点*/ if (flag1) {printf("%d,%d,%dn",i,maxj,max);/*当flag为1时,说明在位置(i,maxj) 是鞍点,输出鞍点及其元素*/ flag2=1; }} if (!flag2) printf("non");/*如果flag2为0,说明没有鞍点,输出no*/ 11} 习 题10 解答 1、D 2、B 3、C 4、B 5、2 6、1)struct node { int data ; struct node *next ; }*p,*q,*w; 2)w = (struct node *)malloc(sizeof(struct node)); 3) w->next=q; p->next=w; 【10.7】编写一个程序,定义一个结构体变量存放日期,输入今天的日期,输出明天的日期。 分析:构造一个表示日期的结构体类型;设计一个函数fundays( )用于计算指定的日期所在月份的天数,若判断指定的日期是闰年,则2月份天数改为29天;在计算明天日期时,要考虑的情况是:今天日期是否有错;今天日期不是月底(计算方法:年数和月数不变,日数加1),今天日期是年底(计算方法:年数加1,月数和日数分别赋值为1),今天日期不是年底但是月底(计算方法:年数不变,月数加1,日数赋值为1)。 程序如下: #include struct sdate { int year; int month; int day; }; int fundays(struct sdate today) { int days; static int tab[]={31,28,31,30,31,30,31,31,30,31,30,31}; if((%4==0 && %100!=0)||( %400==0)) tab[1]=29; days=tab[-1]; return days; } main( ) { struct sdate today, tomorrow; printf("输入今天的日期(格式是:2008,8,10):"); scanf("%d, %d, %d", &, &, &); if((>fundays(today))||>12) { printf("输入的日期有错!nn"); } else { if( } 程序运行结果为: { = ; tomorrow. month= ; = +1; } else if(==12) { = +1; } { } tomorrow. month=1; =1; float ave; }; main( ) { int k; struct score stu[N]; printf("输入学生姓名和成绩:n"); for(k=0; k { printf ("第%d个学生姓名:", k+1); scanf ("%s", stu[k].name); printf ("高等数学,英语,C语言成绩:"); scanf ("%f,%f,%f", &stu[k].ma, stu[k].ave= &stu[k].en, &stu[k].cp); (stu[k].ma+stu[k].en+stu[k].cp)/3; } printf("输出学生成绩:n"); printf("姓名 高等数学 英语 C语言 平均成绩n"); for(k=0; k printf stu[k].name, { else = ; = +1; =1; printf("明天的日期是:%d,%d,%dnn", } ("%-12s%-10.2f%-8.2f%-8.2f%-8.2fn", stu[k].ma, stu[k].en, stu[k].cp, stu[k].ave); } 程序运行结果为: } , tomorrow. month, ); 【10.8】用结构体类型编写一个程序,输入n个学生的高等数学、英语、C语言三门课程的成绩,然后计算平均分数并输出。 程序如下: #include #define N 5 struct score { char name[12]; float ma; float en; float cp; 【10.9】用结构体类型编写一个程序,输入n个客户的姓名和电话号码,然后按姓名的字典顺序排列后12 顺序输出。 分析:构造一个表示客户信息的结构体类型kh;设计一个函数sort()用于对客户的姓名按字典顺序排列 程序如下: #include #include struct kh { char name[16]; char tele[12]; }; void sort(struct kh *p, int n) { int i,j,k; struct kh temp; for(i=0; i { k=i; for(j=i+1; j if(strcmp(p[k].name,p[j].name)>0) k=j; temp=p[k]; p[k]=p[i]; p[i]=temp; } } main( ) { struct kh per[50]; int m, i; char c[2]="y"; printf("请输入:n"); for(m=0; strcmp(c,"y")==0; m++) { printf ("第%d个姓名和电话号码:", m+1); scanf ("%s%s", per[m].name, per[m].tele); printf("n继续输入请按y:"); scanf("%s",c); } sort(per, m); printf("输出客户姓名 电话号码:n"); for(i=0; i { printf ("%-16s%-12sn", per[i].name, per[i].tele); } } 程序运行结果为: 13 【10.10】编写一个程序,建立如下图所示的单链表,然后再将该链表逆序排列并输出。 程序如下: #include #include #define LEN sizeof(struct node) struct node /*定义节点数据类型*/ { int data; struct node * next; }; struct node * create(void); /* 创建链表函数 */ struct node * invert(struct node *); /*对链表逆置的函数*/ void print(struct node *); /*输出链表函数*/ int main() { struct node *h,*t; /*定义一个链表,h为头指针*/ h = create(); /*创建链表*/ printf("创建的链表是:n"); print(h); /*输出链表*/ t=invert(h); /*对链表进行逆置*/ printf("逆置后的链表是:n"); print(t); /*输出逆置后的链表*/ return 0; } struct node * create() /* 创建链表,并返回表头指针。带一个头指针的链表 */ { struct node *head; /* 表头 */ struct node *p; /* 新建结点 */ struct node *tail; /*表尾节点*/ int input; /*输入的数据*/ head = NULL; /* 还没有任何数据,表头为空 */ tail = head; /*尾指针首先指向表头指针*/ printf("请输入结点数据:n"); scanf("%d",&input); while (input!=0) /* 假设data为0表示输入结束 */ { p = (struct node *)malloc(LEN); /* 新建一个结点 */ p->data=input; p->next=NULL; if (head==NULL) /*链表为空表*/ head=p; else tail->next = p; /* 在表尾链接新结点 */ tail = p; /* 新建结点成为表尾 */ printf("请输入结点数据:n"); scanf("%d",&input); } if (head!=NULL) /*输入了数据,已插入节点*/ tail->next = NULL; /* 输入结束,表尾结点的下一个结点为空 */ return head; /* 返回表头指针 */ } void print(struct node *head) { if (head==NULL) { printf("链表空!n"); return; } while(head != NULL) { printf("%4d",head->data); head = head->next; } printf("n"); } struct node * invert(struct node * head) { struct node *p,*q; /*用于逆置的中间变量*/ if (head==NULL) { printf("链表空!n"); return head; 14} p=head; head=NULL; while (p!=NULL) { q=p->next; p->next=head; head=p; p=q; } return head; } 程序运行结果: 习 题11 解答 1、B 2、B 3、D 4、12,2 5、u.a=3132 u.s[0]=32,u.s[1]=31 u.a=1 6、Wangfang,21 7、0 4 5
版权声明:本文标题:《C语言程序设计》清华大学出版社课后答案 内容由热心网友自发贡献,该文观点仅代表作者本人,
转载请联系作者并注明出处:https://m.elefans.com/dongtai/1703524993a59135.html,
本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论