C语言程序设计及实验指导练习及习题参考答案(8--10)
更新时间:2024-06-26 01:24:01 阅读量: 综合文库 文档下载
C语言程序设计及实验指导练习及习题参考答案(8—10章)
8
练习参考答案 1、练习
8-1. 如果有定义:int m, n = 5, *p = &m; 与m = n 等价的语句是 B 。 A.m = *p; B. *p = *&n; C. m = &n; D. m = **p;
8-2. 设计一个程序计算输入的两个数的和与差,要求自定义一个函数sum_diff(float op1, float op2, float *psum, float *pdiff),其中op1 和op2 是输入的两个数,*psum 和*pdiff 是计算得出的和与差。 解答:
#include
float op1, op2, sum, diff;
void sum_diff(float op1, float op2, float *psum, float *pdiff); printf(“input op1 and op2: “); scanf(“%f%f”, &op1, &op2); sum_diff(op1, op2, &sum, &diff);
printf(“%f+%f=%f; %f-%f=%f \\n”,op1,op2,sum,op1,op2,diff); return 0; }
void sum_diff(float op1, float op2, float *psum, float *pdiff) {
*psum = op1 + op2; *pdiff = op1 – op2; }
8-3. 两个相同类型的指针变量能不能相加?为什么? 解答:
不能。因为指针变量是一种特殊的变量,指针变量的值存放的是所指向变量的地址,两个地 址相加并不能保证结果为一个有效的地址值,因而在C 语言中指针变量相加是非法的。 8-4. 根据表8.2 所示,这组数据的冒泡排序其实循环到第6 遍(即n-2)时就已经排好序了, 说明有时候并不一定需要n-1 次循环。请思考如何改进冒泡排序算法并编程实现(提示:当 发现一遍循环后没有数据发生交换,说明已经排好序了)。
解答:设置一个标志变量flag,进入一轮循环前设置为0,在循环中有发生数据交换就改写 flag 值为1。当该轮循环结束后检查flag 值,如果变为1 说明发生了数据交换,还没有排好 序,如果为0 说明没有发生交换,已经排好序。 #include
void bubble (int a[ ], int n); int main(void) {
int n, a[8]; int i;
printf(\scanf(\
printf(\for (i=0; i printf(\for (i=0; i printf(\return 0; } void bubble (int a[ ], int n) /* n 是数组a 中待排序元素的数量 */ { int i, j, t, flag; for( i = 1; i < n; i++ ) { /* 外部循环 */ flag=0; for (j = 0; j < n-i; j++ ) /* 内部循环 */ if (a[j] > a[j+1]) { /* 比较两个元素的大小 */ t=a[j]; a[j]=a[j+1]; a[j+1]=t; /* 如果前一个元素大,则交换 */ flag=1; /* 发生交换,flag 置为1 */ } if (flag==0) /* 如果一轮循环没有发生数据交换,排序结束*/ break; } } 8-5. 重做例8-9,要求使用选择排序算法。 解答: #include void bubble (int a[ ], int n); int main(void) { int n, a[8]; int i; printf(\scanf(\ printf(\for (i=0; i scanf(\bubble(a,n); printf(\ for (i=0; i printf(\return 0; } void bubble (int a[ ], int n) /* n 是数组a 中待排序元素的数量 */ { int i, j, t, index; for( i = 0; i < n-1; i++ ) { /* 外部循环 */ index=i; for (j = i+1; j < n; j++ ) /* 内部循环 */ if (a[j] < a[index]) index = j; t=a[i]; a[i]=a[index]; a[index]=t; } } 8-6. 在使用scanf()函数时,输入参数列表需要使用取地址操作符&,但当参数为字符数组 名时并没有使用,为什么?如果在字符数组名前加上取地址操作符&,会发生什么? 解答: 因为字符数组名的值是一个特殊的固定地址,可以看作是常量指针,因此不需要再使用 取地址符来获取该数组的地址。 如果在字符数组名str 前加上取地址操作符&,那么对其取地址&str 可以看做是这个数 组的第一个元素的地址,由于数组地址和数组第一个元素的地址相同,所以&str 表示地址值和str 表示的地址值是相等的。对scanf()的变长参数列表的话,编译器只负责参数传递,怎么解释后边的几个地址的含义, 是由前边的字符串确定的。所以使用scanf(“%s”,str)和 scanf(“%s”,&str)都能通过编译且正常执行。 8-7. C 语言不允许用赋值表达式直接对数组赋值,为什么? 解答: 数组名可以看作是常量指针,因为不可以对一个常量进行赋值,所以不允许用赋值表达式直接对数组进行赋值。 8-8. 输入一个字符串,把该字符串的前3 个字母移到最后,输出变换后的字符串。比如输入“abcdef”,输出为“defabc”。 解答: # include char line [MAXLINE], str[4]; int i; printf (\gets(line); if (strlen(line)<3) { printf(\字符串长度小于3,不符合要求!\\n\exit(1); } for (i=0;i<3;i++) str[i]=line[i]; str[i]='\\0'; for(i=3; line[i]!='\\0';i++) line[i-3]=line[i]; line[i-3]= '\\0'; strcat(line,str); printf (\return 0; } **8-9. 使用动态内存分配的方法实现例8-9 的冒泡排序。 解答: #include void bubble (int a[ ], int n); int main(void) { int n, *p; int i; printf(\scanf(\ /*为数组p 动态分配n 个整数类型大小的空间 */ if ((p=(int *)calloc(n, sizeof(int))) == NULL) { printf(\exit(1); } printf(\for (i=0; i scanf(\bubble(p,n); printf(\for (i=0; i printf(\free(p); return 0; } void bubble (int a[ ], int n) /* n 是数组a 中待排序元素的数量 */ { int i, j, t; for( i = 1; i < n; i++ ) /* 外部循环 */ for (j = 0; j < n-i; j++ ) /* 内部循环 */ if (a[j] > a[j+1]) /* 比较两个元素的大小 */ { t=a[j]; a[j]=a[j+1]; a[j+1]=t; /* 如果前一个元素大,则交换 */ } } 2 习题参考答案 一、选择题 1.下列语句定义x 为指向int 类型变量a 的指针,其中哪一个是正确的 B 。 A.int a, *x = a; B.int a, *x = &a; C.int *x = &a,a; D.int a, x = a; 2.以下选项中,对基本类型相同的指针变量不能进行运算的运算符是 A 。 A.+ B.- C.= D.== 3.若有以下说明,且0<=i<10,则对数组元素的错误引用是 C 。 int a[] = {0,1,2,3,4,5,6,7,8,9}, *p = a,i; A.*(a+i) B.a[p-a+i] C.p+i D.*(&a[i]) 4.下列程序的输出结果是 B 。 int main(void) { int a[10] = {0,1,2,3,4,5,6,7,8,9}, *p = a+3; printf(“%d”, *++p); return 0; } A.3 B.4 C.a[4]的地址 D.非法 5.对于下列程序,正确的是 A 。 void f(int *p) { *p = 5; } int main(void) { int a, *p; a = 10; p = &a; f(p); printf(“%d”, (*p)++); return 0; } A.5 B.6 C.10 D.11 二、填空题 1. 下列函数在一维数组a 中将x 插入到下标为i(i>=0)的元素前。如果i>=元素的个数,则x 插入到末尾。原有的元素个数存放在指针n 所指向的变量中,插入后元素个数加1。请填 if(*p != 0) count++; if(count == m) { no++; printf(\*p = 0; count = 0; } p++; if(p == num + n) p = num; } p = num; while(*p == 0) p++; printf(\ } 5. 输入一个字符串,将该字符串中从第m 个字符开始的全部字符复制成另一个字符串。m由用户输入,值小于字符串的长度。要求编写一个函数mcopy(char *s, char *t, int m)来完成。 解答: #include char s[80], t[80]; int m; void strmcpy(char *s,char *t, int m); gets(t); scanf(\getchar(); if(strlen(t) < m) printf(\else{ strmcpy(s, t, m); puts(s); } } void strmcpy(char *s, char *t, int m) { t = t + m - 1; while(*t != '\\0') { *s = *t; s++; t++; } *s = '\\0'; } 6. 输入一个字符串,再输入一个字符ch,将字符串中所有的ch 字符删除后输出该字符串。要求定义和调用函数delchar(s,c),该函数将字符串s 中出现的所有c 字符删除。 解答: #include char c; char str[80]; void delchar(char *str, char c); gets(str); scanf(\getchar(); delchar(str, c); printf(\puts(str); } void delchar(char *str, char c) { int i, j; i = j = 0; while(str[i] != '\\0') { if(str[i] != c) { str[j] = str[i]; j++; } i++; } str[j] = '\\0'; } 7. 输入5 个字符串,按由小到大的顺序输出。 解答: #include int i, j, index; char sx[5][80], stemp[80]; for(i=0;i<5;i++) scanf(\for(i=1; i<4; i++) { index=i; for(j=i+1;j<5;j++) if (strcmp(sx[j],sx[index])<0) index=j; strcpy(stemp,sx[i]); strcpy(sx[i],sx[index]); strcpy(sx[index],stemp); } printf(\for (i=0;i<5;i++) puts(sx[i]); return 0; } 8. 编程判断输入的一串字符是否为“回文”。所谓“回文”是指顺读和倒读都一样的字符串。如“XYZYX”和“xyzzyx”都是。 解答: #include char s[80]; int mirror(char *p); gets(s); if(mirror(s) != 0) printf(\else printf(\ } int mirror(char *p) { char *q; q = p; while(*q != '\\0') q++; q--; while(p < q) { if(*p != *q) return 0; p++; q--; } return 1; } 9. 输入一行文字,统计其中的大写字母、小写字母、空格、数字以及其他字符各有多少? 解答: #include char s[80]; char *p; int blank, digit, lower, other, upper; gets(s); upper = lower = blank = digit = other = 0; for(p = s; *p != '\\0'; p++) if(*p >= 'A' && *p <= 'Z') upper++; else if(*p >= 'a' && *p <= 'z') lower++; else if(*p >= '0' && *p <= '9') digit++; else if(*p == ' ') blank++; else other++; printf(\other); } 10. 编写函数strcomp(s1, s2),实现两个字符串的比较,返回值分别为1、0、-1表示s1>s2, s1=s2,s1 int strcomp(char *s1,char *s2) { for (;*s1!=?\\0?;s1++,s2++) if (*s1!=*s2) break; if (*s1-*s2>0) return 1; else if (*s1-*s2<0) return -1; else return 0; } **11. 输入学生人数后输入每个学生的成绩,最后输出学生的平均成绩、最高成绩和最低成绩。要求使用动态内存分配来实现。 解答: # include int n, i; float *p, sum, max, min, avg; printf(\ scanf(\ /*为数组p 动态分配n 个浮点数float 类型大小的空间 */ if ((p=(float *)calloc(n, sizeof(float))) == NULL) { printf(\exit(1); } sum=0.0; max=-1; /*初始化 */ min=1000; printf(\提示输入n 个整数 */ for (i = 0; i < n; i++) { scanf(\sum=sum+*(p+i); if (min>*(p+i)) min=*(p+i); if (max<*(p+i)) max=*(p+i); } avg=sum/n; printf(\free(p); /* 释放动态分配的空间 */ return 0; } 3 实验指导教材参考答案 一、调试示例 利用指针指向2 个整型变量,并通过指针运算找出两个数中的最大值,输出到屏幕上。 (源程序error08_1.cpp) 源程序(有错误的程序) #include int max, x, y, *pmax, *px, *py; scanf(\ *px = &x; /* 分别对px、py 和pmax 三个指针进行赋值*/ *py = &y; /* 让其分别指向x、y 和max 三个变量*/ *pmax = &max; /* 其中,max 用来保存x、y 中较大的变量*/ *pmax = *px; /* 调试时设置断点 */ if(pmax < py) pmax = py; printf(\return 0; } 运行结果(改正后程序的运行结果) 3 5 max = 5 改错汇总 错误行号: 7 正确语句: px = &x; 错误行号: 8 正确语句: py = &y; 错误行号: 9 正确语句: pmax = &max; 错误行号: 11 正确语句: if(*pmax < *py) 错误行号: 12 正确语句: *pmax = *py; 二、改错题 改正下列程序中的错误,有n 个整数,使前面各数顺序循环移动m 个位置(m After moved: 3 4 5 1 2 源程序(有错误的程序) 1 #include 2 void mov(int *x, int n, int m); 3 int main(void) 4 { 5 int a[80], i, m, n, *p; 6 7 printf(\8 scanf(\9 for(p = a, i = 0; i < n; i++) 10 scanf(\11 mov(a,n,m); 12 printf(\13 for(i = 0; i < n; i++) 14 printf(\15 16 return 0; 17 } 18 void mov(int *x, int n, int m) 19 { 20 int i,j,k; 21 for(i = 0; i < m; i++){ 22 23 for(j = n-1; j > 0; j--) 24 x[j] = x[j - 1]; 25 x[0] = x[n – 1]; 26 } 27 } 改错汇总 错误行号: 10 正确语句: scanf(\行号: 22 增加语句: k = x[n-1]; 错误行号: 25 正确语句: x[0] = k; 三、编程题 1. 编写程序计算输入的两个实数的和与差。要求自定义一个函数sum_diff(float op1, float op2,float *psum, float *pdiff),其中op1 和op2 是输入的两个实数,*psum 和*pdiff 是计算得出的和与差。自定义main 函数,并在其中调用sum_diff 函数。 输入输出示例 input op1 and op2 : 4 6 4.000000+6.000000=10.000000; 4.000000-6.000000=-2.000000 解答:参见8.3.1 节中8-2 题。 2. 编写程序拆分输入实数的整数部分与小数部分。要求自定义一个函数void splitfloat(float x,int *intpart, float *fracpart),其中x 是被拆分的实数,*intpart 和*fracpart 分别是将实数x 拆分出来的整数部分与小数部分。自定义main 函数,并在其中调用splitfloat 函数。 输入输出示例 12.4567 The intpart is: 12 The fracpart is: 0.456700 解答: #include void splitfloat(float x, int *intpart, float *fracpart); int main(void) { float x, frac_part; int int_part; scanf(\ splitfloat(x, &int_part, &frac_part); printf(\printf(\return 0; } void splitfloat(float x, int *intpart, float *fracpart) { if(x<0) x=-x; *intpart=(int)x; *fracpart=x-*intpart; } 3. 定义函数void sort(int a[],int n),用选择法对数组a 中的元素升序排序。自定义main 函数,并在其中调用sort 函数。 输入输出示例 Input n (n<=10): 6 Input array of 6 integers:1 5 –9 2 4 –6 After sorted the array is: -9 –6 1 2 4 5 解答: #include void swap (int *px, int *py); void sort(int a[ ], int n); int main(void) { int n, a[10], i; printf(\scanf(\ printf(\:\for (i=0; i scanf(\sort (a,n); printf(\for (i=0; i printf(\return 0; } void sort(int a[ ], int n) { int i, j, index; for( i = 0; i < n-1; i++ ) { index=i; for (j = i+1; j < n; j++ ) if (a[j] < a[index]) index = j; swap (&a[i], &a[index]); } } void swap (int *px, int *py) { int t; t = *px; *px = *py; *py = t; } 4. 在数组中查找指定元素。输入一个正整数n (1 输入输出示例(运行2 次) 第一次运行: Input n: 3 Input 3 integers:1 2 -6 Input x:2 index = 1 第二次运行: Input n: 5 Input 5 integers:1 2 2 5 4 Input x:0 Not found 解答: #include int i, n, res, x; int a[10]; int search(int list[], int n, int x); scanf(“%d”,&n); for(i = 0; i < n; i++) scanf(\scanf(\res = search(a, n, x); if(res != -1) printf(\else printf(\return 0; } int search(int list[], int n, int x) { int i; for(i = 0; i < n; i++) if(list[i] == x) return i; return -1; } 5. 有n 个人围成一圈,按顺序从1 到n 编好号。从第一个人开始报数,报到3 的人退出圈子,下一个人从1 开始重新报数,报到3 的人退出圈子。如此下去,直到留下最后一个人。 问留下来的人的编号。 输入输出示例 Input n: 5 Last No is: 4 解答:参见8.3.2 节中程序设计第4 题。 9 1 练习参考答案 9-1 上机运行例9-1 的程序。 解答:(略) 9-2 定义一个能够表示复数的结构类型,一个复数包括实数与虚数两个部分。 解答: struct complex{ float real; float imaginary; }; 9-3 人的出生日期由年、月、日组成,请在例9-1 中的通讯录结构中增加一个成员:出生日期,用嵌套定义的方式重新定义该结构类型。 解答: struct date{ int year; int month; int day; }; struct nest_student{ int num; char name[10]; struct date birthday; /* 定义出生日期 */ int computer, english, math; double average; }; 9-4 例9-2 中,如果不定义函数count_average (),应该如何改写主函数,以实现程序功能。 解答: 将主函数中的语句: s1.average = count_average (s1); /*函数调用,结构变量作为函数参数*/ 改写为: s1.average = (s1.math + s1.english + s1.computer) / 3.0; 9-5 例9-2 中,如果要计算的是三门课程的课程平均成绩,应该如何改写程序。 解答: int main(void) { int i, n; double math_ave, english_ave, computer_ave; struct student s1; /* 定义结构变量 */ printf(\scanf(\ printf(\\\n”); math_ave = english_ave = computer_ave = 0; for(i = 1; i <= n; i++){ printf(\ scanf(\math_ave = s1.math; english_ave = s1.english; computer_ave = s1.computer; } printf(\computer_ave); return 0; } 9-6 定义一个包含5 名学生信息的结构数组,并对该结构数组的所有元素进行则始化。 解答: struct student{ int num; char name[10]; int computer, english, math; double average; }; struct student s[5]={{30101, \张一\李二\王三\赵四\刘五\9-7 参考例9-3,输入并保存10 个学生的成绩信息,分别输出平均成绩最高和最低的学生信息。 解答: #include struct student{ /*学生信息结构定义*/ int num; /* 学号 */ char name[10]; /* 姓名 */ int computer, english, math ; /* 三门课程成绩 */ double average; /* 个人平均成绩 */ }; struct student students[10]; /* 定义结构数组 */ int main(void) { int i, max,min; /* 输入10 个学生的记录*/ for(i = 0; i < 10; i++){ printf(\ scanf(\&students[i].english, &students[i].computer); students[i].average=(students[i].math+students[i].english+students[i].computer)/3.0; } /* 查找平均成绩最高、最低分学生的数组下标值 */ max=min=0; for( i = 1; i < 10; ++i ){ if(students[i].average > students[max].average) max=i; if(students[i].average < students[min].average) min=i; } /*输出平均成绩最高和最低的学生信息*/ printf(\最高分学生信息:学号:%d,姓名:%s,数学:%d,英语:%d,计算机:%d,平均分:%.2lf \\n\students[max].computer, students[max].average); printf(\最低分学生信息:学号:%d,姓名:%s,数学:%d,英语:%d,计算机:%d,平均分:%.2lf \\n\students[min].computer, students[min].average); return 0; } 9-8 定义一个struct student 类型的结构指针,用其实现一个学生信息的输入和输出。 解答: struct student{ /*学生信息结构定义*/ int num; /* 学号 */ char name[10]; /* 姓名 */ int computer, english, math ; /* 三门课程成绩 */ double average; /* 个人平均成绩 */ }s, *p; p = &s; scanf(\9-9 改写例9-4 中的函数update_score(),将第一个形参改为结构数组形式。 解答: int update_score(struct student s[ ], int n, int num, int course, int score) { int i,pos; for(i = 0; i < n; i++) /* 按学号查找 */ if(s[i].num == num) break; if(i < n) /* 找到,修改成绩 */ { switch(course){ case 1: s[i].math = score; break; case 2: s[i].english = score; break; case 3: s[i].computer = score; break; } pos = i; /* 被修改学生在数组中的下标 */ } else /* 无此学号 */ pos = -1; return pos; } 2 习题参考答案 一、选择题 1.下面定义结构变量的语句中错误的是 D 。 A.struct student{ int num; char name[20]; } s; B.struct { int num; char name[20]; } s; C.struct student{ int num; char name[20]; }; struct student s; D.struct student{ int num; char name[20]; }; student s; 2.如果有定义语句: struct {int x, y; } s[2] = { { 1, 3 }, { 2, 7 } }; 则语句:printf(“%d\\n”, s[0].y/s[1].x ); 输出结果为 B 。 A.0 B.1 C.2 D.3 3.根据下面的定义,能打印出字母M 的语句是 C 。 struct person{ char name[10]; int age; } c[10] = { “John”, 17, “Paul”, 19, “Mary”, 18, “Adam”, 16 }; A.printf(“%c”, c[3].name); B.printf(“%c”, c[3].name[1]); C.printf(“%c”, c[2].name[0]); D.printf(“%c”, c[2].name[1]); 4.设有如下定义,则对data 中的a 成员的正确引用是 B 。 struct sk{ int a; float b; } data, *p=&data; A.(*p).data.a B.(*p).a C.p->data.a D.p.data.a 5.对于以下结构定义,(*p)->str++中的++加在 D 。 struct { int len; char *str; } *p; A.指针str 上 B.指针p 上 C.str 指向的内容上 D.语法错误 二、填空题 1.“.”称为 成员(分量) 运算符,“->”称为 指向 运算符。 2.完成下列程序,该程序计算10 名学生的平均成绩。 #include char name[20]; int score; }; struct student stud[10]; int main(void) { int i , sum = 0 ; for(i = 0; i < 10; i++){ scanf(\&stud[i].num, stud[i].name , &stud[i].score); sum += stud[i].score; } printf(\return 0; } 3.下列程序读入时间数值,将其加1 秒后输出,时间格式为:hh: mm: ss,即小时:分钟: 秒,当小时等于24 小时,置为0。 #include int hour, minute, second; } time; int main(void) { scanf(\time.second++; if( time.second == 60){ time.minute++ ; time.second = 0; if(time.minute == 60){ time.hour++; time.minute = 0; if( time.hour == 24 ) time.hour = 0; } } printf (\return 0; } 4.写出下面程序的运行结果 1 2 A B struct s1{ char c1, c2; int n; }; struct s2{ int n; struct s1 m; } m = {1, {?A?, ?B?, 2} }; int main(void) { printf(“%d\\t%d\\t%c\\t%c\\n”, m.n, m.m.n, m.m.c1, m.m.c2); return 0; } 5.写出下面程序的运行结果 23, wang, 98.5, wang 。 struct abc{ int a; float b; char *c; }; int main(void) { struct abc x = {23,98.5,\struct abc *px = &x; printf(\return 0; } 三、程序设计题 1.职工工资项目包括编号、姓名、基本工资、奖金、保险、实发工资,其中:实发工资 = 基 本工资 + 奖金 - 保险。输入10 个职工的前5 项信息,计算并输出其实发工资。 解答: #include struct employee{ /* 定义结构类型employee */ int num; char name[20]; float jbgz, jj, bx, sfgz; }; int main(void) { int i; struct employee e; /* 定义结构类型变量 e */ for(i = 1; i <= n; i++){ printf(\请输入第%d个职工的信息: \scanf(\ scanf(\e.sfgz = e.jbgz + e.jj - e.bx; printf(\编号:%d 姓名:%s实发工资:%.2f\\n\} return 0; } 2.中国有句俗话:“三天打鱼,两天晒网”。某人从1990 年1 月1 日起开始“三天打鱼, 两天晒网”,问这个人在以后的某一天(输入1 个天数)中是在“打鱼”,还是在“晒网”。 要求用结构形式定义日期(年、月、日)。 解答: 提示:先计算出输入的日期与1990 年1 月1 日相差的天数,然后求除5 后的余数,再 将余数对照“三天打鱼,两天晒网”,得出最后结论(注:若余数为0,则为“晒网”)。 #include int year, month, day; }; int day_tab[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; int main(void) { struct date today; int year, i, lp, count=0; scanf(“%d%d%d”,&today.year, &today.month, &today.day); /*输入日期*/ /*计算相差天数*/ for(year=1990; year lp= year%4==0&& year0!=0|| year@0==0; for(i=1; i<13; i++) count+=day_tab[lp][i]; } lp= today.year%4==0&& today.year0!=0|| today.year@0==0; for(i=1; i /*求除5 后的余数,再将余数对照“三天打鱼,两天晒网”,得出最后结论 */ count=count%5; if(count>=1&&count<=3) printf(“这一天是打鱼\\n”); else printf(“这一天是晒网\\n”); return 0; } 3.利用结构变量求解两个复数之积: (3+4i) × (5+6i)。 提示:求解(a1+a2i)×(b1+b2i),乘积的实部为:a1×b1 - a2×b2,虚部为:a1×b2 + a2×b1。 解答: #include struct complex cmult(struct complex , struct complex); void main() { struct complex a={3,4}, b={5,6}, c; c=cmult(a, b); printf(“(%d+%di)×(%d+%di) =%d+%di\\n”, a.real, a.im, b.real, b.im, c.real, c.im); } struct complex cmult(struct complex a , struct complex b) { struct complex w; w.real=a.real*b.real – a.im*b.im; w.im=a.real*b.im + a.im*b.real; return w; } 4.编写程序,从键盘输入10 本书的名称和定价并存入结构数组中,从中查找定价最高和最 低的书的名称和定价,并输出。 解答: #include { char name[10]; float price; }; int main() { int i,maxl,minl; struct book test[NUMBER]; printf(“Input 10 book?s name and price\\n”); for(i=0; i scanf(“%s%f”, test[i].name, &test[i].price); maxl=minl=0; for(i=1; i { if(test[maxl].price printf(“Max Price: %f, %s\\n”, test[maxl].price, test[maxl].name); printf(“Min Price: %f, %s\\n”, test[minl].price, test[minl].name); return 0; } 5.建立一个通讯录结构,包括姓名、生日、电话号码以及住址。编写程序,输入n(n≤10) 个联系人信息,按照年龄从大到小依次显示他们的信息。 解答: #include char name[10]; /* 姓名 */ int birthday; /* 生日 */ char phone[15]; /* 电话号码 */ char address[50]; /* 住址 */ }; void sort(struct friends_list s[], int n) /*按生日日期从小到大排序*/ { int i, j; struct friends_list temp; for(i=1; i if(s[j].birthday > s[j+1].birthday) {temp=s[j]; s[j]=s[j+1]; s[j+1]=temp; } } int main(void) { int i, n; struct friends_list friends[10]; scanf(“%d”, &n); for(i=0; i scanf(\friends[i].address); /*按年龄从大到小排序*/ sort(friends, n); for(i=0;i printf(\friends[i].address); return 0; } 6.输入10 个学生的学号、姓名和成绩,输出学生的成绩等级和不及格人数。每个学生的记 录包括学号、姓名、成绩和等级,要求定义和调用函数set_grade()根据学生成绩设置其等 级,并统计不及格人数,等级设置:85-100 为A,70-84 为B,60-69 为C,0-59 为D。 解答: /* 设置学生成绩等级并统计不及格人数(结构指针作为函数参数) */ #include char name[20]; int score; char grade; }; int set_grade(struct student *p); int main(void) { struct student stu[N], *ptr; int i, count; ptr = stu; printf(\for(i = 0; i < N; i++){ printf(\提示输入第i 个同学的信息 */ scanf(\} count = set_grade(ptr); printf(\printf(\for(i = 0; i < N; i++) printf(\return 0; } int set_grade(struct student *p) { int i, n = 0; for(i = 0; i < N; i++, p++){ if(p->score >= 85) p->grade = 'A'; else if(p->score >= 70) p->grade = 'B'; else if(p->score >= 60) p->grade = 'C'; else{ p->grade = 'D'; n++; } } return n; } 7.在本章例题的基础上编写一个学生信息综合管理程序,要求能够实现对学生信息的新建、 输出、修改、查询、按平均成绩排序等功能。 解答: 例9-1 中的函数new_student()、search_student()、output_student()分别实现了学生信息的 新建、查询和输出; 例9-3 实现了按学生平均成绩排序,将其排序功能程序封装在自定义函数sort(struct student students[ ], int n)中; 例9-3 中的函数update_score()实现了学生成绩修改; 将这5 个函数放在一个程序文件中,主函数在例9-1 的基础上修改如下: #include struct student{ /*学生信息结构类型定义*/ int num; /* 学号 */ char name[10]; /* 姓名 */ int computer, english, math; /* 三门课程成绩 */ double average; /* 个人平均成绩 */ }; int Count = 0; /* 全局变量,记录当前学生总数 */ int main(void) { int choice, num, course, score; struct student students[MaxSize]; /* 定义学生信息结构数组 */ do{ /* 用户操作界面 */ printf(\scanf(\switch(choice){ case 1: new_student(students); break; case 2: printf(“Please input the student?s number:”); scanf(“%d”, &num); search_student(students, num); break; case 3: output_student(students); break; case 4: sort(students, Count); break; case 5: printf(\scanf(“%d”, &num); printf(\scanf(“%d”, &course); printf(\scanf(“%d”, &score); update_score(students, Count, num, course, score); break; case 0: break; } } while(choice != 0); printf(\return 0; } 3 实验指导教材参考答案 一、调试示例 改正下列程序中的错误。输入一个正整数n(3≤n≤10),再输入n 个职员的信息(表 9.1),要求输出每位职员的姓名和实发工资(实发工资=基本工资+浮动工资-支出)。(源程 序error09_1.c) 表9.1 工资表 姓 名 基本工资 浮动工资 支出 zh ao 240.00 400.00 75.00 qi an 360.00 120.00 50.00 zh ou 560.00 150.00 80.00 源程序(有错误的程序) 1 #include 4 struct emp{ 5 char name[10]; 6 float jbgz; 7 float fdgz; 8 float zc; 9 }; 10 emp s[10]; 11 int i, n; 12 13 printf(\14 scanf(\15 for (i = 0; i < n; i++) 16 scanf(\17 for (i = 0; i < n; i++) /* 调试时设置断点 */ 18 printf (\,实发数:%.2f\\n\19 20 return 0; 21 } /* 调试时设置断点 */ 运行结果(改正后程序的运行结果) n=3 zhao 240 400 75 qian 360 120 50 zhou 560 150 80 zhao 实发数:565.00 qian 实发数:430.00 zhou 实发数:630.00 改错汇总 错误行号: 10 正确语句: struct emp s[10]; 错误行号: 16 正确语句: scanf(\&s[i].zc); 二、改错题 建立一个有n(3 1 黄岚 78 83 75 2 王海 76 80 77 3 沈强 87 83 76 4 张枫 92 88 78 5 章盟 80 82 75 总分最高的学生是:张枫,258 分 源程序(有错 .的程序) 1 #include 9 int i, j, k, n, max=0; 10 printf(\11 scanf(\12 for (i = 0; i < n; i++){ 13 scanf(\14 15 for(j = 0; j < 3; j++){ 16 scanf(\17 student[i].sum += student[i].score[j]; 18 } 19 } 20 k = 0; max = student[0].sum; 21 for(i = 1; i < n; i++) 22 if(max < student[i].sum) { 23 k = i; 24 25 } 26 printf(\总分最高的学生是: %s,%d 分\\n\27 return 0; 28 } 改错汇总 错误行号: 8 正确语句: }student[10]; 错误行号: 14 正确语句: student[i].sum=0; 错误行号: 24 正确语句: max=student[i].sum; 三、编程题 1.时间换算。用结构类型表示时间内容(时间以时、分、秒表示),输入一个时间数值,再 输入一个秒数n(n<60),以h:m:s 的格式输出该时间再过n 秒后的时间值(超过24 点就从0 点开始计时)。 输入输出示例 11:59:40 30 12:0:10 解答: #include void timecal(struct time *p,int n); int main(void) { int n; struct time time1,*p; scanf(\scanf(\p=&time1; timecal(p,n); printf(\} void timecal(struct time *p,int n) { p->s+=n; if(p->s>=60) { p->s-=60; p->m++; if(p->m==60) { p->m=0; p->h++; if(p->h==24) p->h=0; } } } 2.计算平均成绩。建立一个学生的结构记录,包括学号、姓名和成绩。输入整数n(n<10), 再输入n 个学生的基本信息,要求计算并输出他们的平均成绩(保留2 位小数)。 输入输出示例 n=3 1 zhang 70 2 wang 80 3 qian 90 80.00 解答: #include struct student{ /*学生信息结构定义*/ int num; /* 学号 */ char name[10]; /* 姓名 */ int score; /* 成绩 */ }; int main(void) { int i, n; double ave=0; struct student s1; /* 定义结构变量 */ printf(\scanf(\ for(i = 1; i <= n; i++){ scanf(\ave += s1.score; } ave = ave/n; printf(\return 0; } 3.利用结构变量求解两个复数之积: (3+4i) × (5+6i)。 提示:求解(a1+a2i)×(b1+b2i),乘积的实部为:a1×b1 - a2×b2,虚部为:a1×b2 + a2×b1。 输入输出示例 (3+4i) × (5+6i)= -9+38i 解答:参见9.3.2 程序设计题第3 题 4.编写程序,从键盘输入n(n<10)本书的名称和定价并存入结构数组中,从中查找定价最高 和最低的书的名称和定价,并输出。 输入输出示例 n=3 C 程序设计 21.5 VB 程序设计 18.5 Delphi 程序设计 25.0 价格最高的书:Delphi 程序设计,价格:25.00 价格最低的书:VB 程序设计,价格:18.50 解答: #include int i,n,max_index,min_index; struct{ char name[50]; double price; }book[10]; printf(“n=”); scanf(\for(i=0;i scanf(\max_index = min_index = 0; for(i=1;i if(book[i].price > book[max_index].price) max_index=i; if(book[i].price < book[min_index].price) min_index=i; } printf(\价格最高的书: %s, 价格: %.2lf\\n\book[max_index].name,book[max_index].price); printf(\价格最低的书: %s , 价格: %.2lf\\n\book[min_index].price); } 5.编写程序,输入一个日期(年、月、日),计算并输出该日是该年中的第几天。要求自定 义函数用于计算某日是该年中的第几天,用结构指针作为函数参数(注意闰年问题)。 输入输出示例 2006 3 5 64 解答: #include int day_of_year(struct DATE *p); int main(void) { scanf(\printf(\} int day_of_year(struct DATE *p) { int k, leap; int tab[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; leap=(p->year%4==0&&p->year0!=0||p->year@0==0); for(k = 1; k < p->month; k++) p->day = p->day + tab[leap][k]; return p->day; } 6.(选作) 通讯录排序。通讯录的结构记录包括:姓名、生日、电话号码,其中生日又包 括三项:年、月、日。定义一个嵌套的结构类型,输入n(n<10)个联系人的信息,再按他们 的年龄从大到小的顺序依次输出其信息。 输入输出示例 n=3 zhang 1985 04 03 13912345678 wang 1982 10 20 0571-88018448 qian 1984 06 19 13609876543 wang 1982/10/20 0571-88018448 qian 1984/6/19 13609876543 zhang 1985/4/3 13912345678 解答: #include struct date{ /* 日期结构 */ int y, m ,d ; }; struct friends_list{ char name[10]; /* 姓名 */ struct date birthday; /* 生日 */ char phone[15]; /* 电话号码 */ }; void sort(struct friends_list s[], int n) /*按生日日期从小到大排序*/ { int i, j, b1, b2; struct friends_list temp; for(i=1; i b1 = (s[j].birthday.y*100+ s[j].birthday.m)*100+ s[j].birthday.d; b2 = (s[j+1].birthday.y*100+ s[j+1].birthday.m)*100+ s[j+1].birthday.d; if( b1 > b2) {temp=s[j]; s[j]=s[j+1]; s[j+1]=temp; } } } int main(void) { int i, n; struct friends_list friends[10]; printf(“n=”); scanf(“%d”, &n); for(i=0; i scanf(\&friends[i].birthday.d, friends[i].phone); /*按年龄从大到小排序*/ sort(friends, n); for(i=0;i printf(\friends[i].birthday.m, friends[i].birthday.d, friends[i].phone); return 0; } 10 1 练习参考答案 10-1 若要用递归函数计算sum=1+2+3+…+n(n 为正整数),请写出该递归函数的递归式子 及递归出口。 解答: 递归式子: sum(i) = sum(i-1) + i; i>0 递归出口: sum(i) = 0; i = 0 10-2 请完成下列宏定义: ① MIN(a,b) 求a,b 的最小值 ② ISLOWER(c) 判断c 是否为小写字母 ③ ISLEAP(y) 判断y 是否为闰年 ④ CIRFER(r) 计算半径为r 的圆周长 解答: ① MIN(a, b):求a, b 的最小值。 #define MIN(a, b) (a) < (b) ? (a): (b) ② ISLOWER(c):判断c 是否为小写字母。 #define ISLOWER(c) (((c) >= 'a') && ((c) <= 'z') ) ③ ISLEAP(y):判断y 是否为闰年。 #define ISLEAP(y) ((y) % 4 == 0 && (y) % 100 != 0) || ((y) % 400 = = 0) ④ CIRFER(r):计算半径为r 的圆周长。 #define PI 3.14159 #define CIRFER(r) 2*PI*(r) 10-3 分别用函数和带参宏实现从3 个数中找出最大数,请比较两者在形式上和使用上的区 别。 解答: 1) 函数实现 int max( int x, int y, int z ) { int t; if(x>=y) if (x>=z) t=x; else t=z; else if (y>=z) t=y; else t=z; return t; } 2) 宏实现 #define MAX( x, y, z ) x>=y? (x>=z? x:z) : (y>=z? y:z) 两者在定义形式上完全不同。使用上函数是在执行时,从主调函数转到函数max(),然 后再返回到主调函数,函数体始终存在;而宏是在编译预处理时,用条件表达式去替换 MAX(int x, int y, int z ),等程序执行时,执行的是条件表达式,而不再存在MAX(int x, int y, int z )的式子。 2 习题参考答案 一、选择题 1.要调用数学函数时,在#include 命令行中应包含 C 。 A.”stdio.h” B.”string.h” C.”math.h” D.”ctype.h” 2.对于以下递归函数f,调用f(4),其返回值为 A 。 int f(int n) { if (n) return f(n - 1) + n; else return n; } A.10 B.4 C.0 D.以上均不是 3.执行下列程序: #define MA(x, y) ( x*y ) i = 5; i = MA(i, i + 1) – 7; 后变量i 的值应为 B 。 A.30 B.19 C.23 D.1 4.宏定义“#define DIV(a, b) a/b”,经DIV(x + 5, y - 5) 引用,替换展开后是 A 。 A.x + 5 / y - 5 B.x + 5 / y – 5 C.(x + 5) / (y - 5) D.(x + 5) / (y - 5); 5.定义带参数的宏“#define JH(a,b,t) t = a; a = b; b = t”,对两个参数a、b 的值进行交换,下 列表述中哪个是正确的 C 。 A.不定义参数a 和b 将导致编译错误 B.不定义参数a、b、t 将导致编译错误 C.不定义参数t 将导致运行错误 D.不需要定义参数a、b、t 类型 6.执行下面程序,正确的输出是 A 。 int x = 5, y = 7; void swap ( ) { int z ; z = x ; x = y ; y = z ; } int main(void) { int x = 3, y = 8; swap ( ) ; printf ( \return 0 ; } A.3, 8 B.8, 3 C.5, 7 D.7, 5 7.下面说法中正确的是 A 。 A.若全局变量仅在单个C 文件中访问,则可以将这个变量修改为静态全局变量,以降低模 块间的耦合度 B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低 模块间的耦合度 C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑变量 生命周期问题 D.静态全局变量使用过多,可那会导致动态存储区(堆栈)溢出 二、填空题 1.执行完下列语句段后, i 值为 2 。 int i; int f(int x) { static int k = 0; x += k++; return x; } i=f(f(1)); 2.执行完下列语句段后, i 的值为 5 。 int i; int f(int x) { return ((x>0)? f(x-1)+f(x-2):1); } i=f(3); 3.下列程序段A 与B 功能等价,请填写程序段B 中相应语句。 程序段A: int f( int n ) { if(n<=1) return n; else return f(n-1)+f(n-2); } 程序B: int f( int n ) { int t, t0, t1 ; t0=0; t1=1; t=n; while ( n>1 ) { t = t0+t1 ; t0 = t1; t1 = t; n - -; } return t ; } 4.下面程序用于计算 f(k , n)=1k+2k+…+nk ,其中power(m , n )求mn。请填写程序中相应 语句。 # include for( i=1 ; i<=n ; i++) p = p * m ; return p ; } int f(int k , int n) { int i ; int s=0 ; for( i=1 ; i<=n ; i++) s = s + power(i, k) ; return s ; } int main(void) { int k , n ; scanf(“%d%d”, &k, &n ) ; printf(“f(%d, %d)=%ld” , k, n, f(k, n)) ; return 0; } 5.下列递归程序的输出结果为 g=4,g=3,k=6 。 #include case 2: return 2; } printf(\ return fib(g-1) + fib(g-2); } int main(void) { int k; k = fib(4); printf(\return 0; }
正在阅读:
C语言程序设计及实验指导练习及习题参考答案(8--10)06-26
黄河三角洲大气环境污染现状08-24
有关母爱的高中作文02-04
关联词语可分为8种类型08-01
学生会实践部工作总结04-13
六层砖混结构住宅楼工程施工组织设计106-22
计量器具强制检定明细目录-105-06
有关于企业文化对企业的重要性论文05-26
图书馆大扫除新闻稿04-02
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 习题
- 程序设计
- 练习
- 答案
- 语言
- 指导
- 参考
- 实验
- 10
- 浅谈国内外绘本中的插画艺术
- 第三章 消费者行为习题
- 2011年高职单招语文科练习卷1
- 复变函数期末模拟题
- 语文人教版五年级下册1-8单元看拼音写词语
- 期刊投稿 地 址和电子邮箱(大全)
- 中国乙烯裂解炉行业发展研究报告 - 图文
- 2019年高考语文核按钮【课标版】附录1-4合编
- 福建教育资源公共服务平台空间美化方法
- 建设单位工程管理制度
- SL176-2007《水利水电工程施工质量检验与评定规程》 - word版
- 小学三年级50道应用题
- 人教版一年级数学下册期末总复习试题全集
- General Knowledge(专八)
- 城市轨道交通毕业论文设计
- 医学影像物理学资料 第三版
- 怎样写好话题作文
- 人音版初中八年级上册音乐教案 全册
- 导游实务模拟题八
- 调查问卷A