第七章 用函数实现模块化程序设计(习题)
第七章 课后习题
1、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。
最大公约数
1)穷举法
#include <stdio.h> // 穷举法 int gcd(int a,int b) { if(a==0) return b; else if(b==0) return a; else if(a==b) return a; int gcd_res=a>b?a:b; while(gcd_res>1) { if((a%gcd_res==0)&&(b%gcd_res==0)) return gcd_res; gcd_res--; } return gcd_res; // 1 } int main() { int a,b; printf("Please enter two number:\n"); scanf("%d,%d",&a,&b); int gcd_result=gcd(a,b); printf("最大公约数为:%d\n",gcd_result); return 0; }
2)相减法
int gcd(int a,int b) { if(a==0) return b; else if(b==0) return a; else if(a==b) return a; int gcd_res; while(a!=b) { gcd_res=a>b?(a-=b):(b-=a); } return gcd_res; // 1 }
3)欧几里得辗转相除法
① 循环实现
int gcd(int a,int b) { if(a==0) return b; else if(b==0) return a; else if(a==b) return a; int mod=a%b; whlie(mod) //当相模不为0时 { a=b; // b的值赋值给a b=mod; // mod=a%b; } return b; }
④ 递归实现
int gcd(int a,int b) { if(b==0) return a; else return gcd(b,a%b); return b; }
最小公倍数
1)穷举法
int lcm(int a,int b) { // 穷举法 if(a*b==0) return 0; int lcm_res=a>b?a:b; while(1) { if((lcm_res%a==0)&&(lcm_res%b==0)) break; lcm_res++; } return lcm_res; } int main() { int a,b; printf("Please enter two number:\n"); scanf("%d,%d",&a,&b); int lcm_result=lcm(a,b); printf("最大公倍数为:%d\n",lcm_result); return 0; }
2)公式法
#include <stdio.h> int gcd(int a,int b) { // 欧几里得辗转相除法 if(b==0) return a; else return gcd(b,a%b); return b; } int lcm(int a,int b) { // 公式法 lcm=a*b/gcd(a,b) if(a*b==0) return 0; return (a*b/gcd(a,b)); } int main() { int a,b; printf("Please enter two number:\n"); scanf("%d,%d",&a,&b); int gcd_result=gcd(a,b); int lcm_result=lcm(a,b); printf("最大公约数为:%d\n",gcd_result); printf("最大公倍数为:%d\n",lcm_result); return 0; }
2、写一个判素数的函数,在主函数输入一个整数,输出是否为素数的信息。
#include <stdio.h> #include <math.h> int IsPrime(int a) { int i,flag; double k; k=sqrt(a); for(i=2;i<=k;i++) { if(a%i==0) return flag=0; else return flag=1; } } int main() { printf("Please enter a number:\n"); scanf("%d",&a); int flag=IsPrime(a); if(flag) printf("%d 是一个素数\n",a); else printf("%d 不是一个素数\n",a); return 0; }
3、写一个函数,使给定的一个3X3的二维整型数组转置,即行列互换。
#include<stdio.h> void PrintArray(int ar[3][3]) { // 运行结果: for(int i=0; i<3; i++) { for(int j=0; j<3;j++) { printf("%d ", ar[i][j]); } printf("\n"); } } void ReverseArray(int ar[3][3]) { int tmp; for(int i=0; i<3; i++) { for(int j=0; j<i;j++) { if(i != j) //中间数不发生变化 { //交换两个数 tmp = ar[i][j]; ar[i][j] = ar[j][i]; ar[j][i] = tmp; } } } } int main() { int array[3][3] = { {1,2,3}, {4,5,6}, {7,8,9} }; printf("转置前:\n"); PrintArray(array); ReverseArray(array); //进行数组转置 printf("转置后:\n"); PrintArray(array); return 0; }
4、写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。
第一种实现方式(这种个人觉得好难理解哈哈哈)
#include <stdio.h> #include <string.h> int main() { void trans_str(char str[]); char str[10]; gets(str); trans_str(str); puts(str); return 0; } void trans_str(char str[]) { int i; int len=strlen(str); char temp; for(i=0;i<len/2;i++) { temp=str[i]; str[i]=str[len-i-1]; str[len-i-1]=temp; } }
第二种实现方式
#include<stdio.h> #include<string.h> void ReverseString(char str[]) { int start, end; char tmp; start = 0; end = strlen(str)-1; //字符数组小标从0开始,所以-1 while(start < end) { tmp = str[start]; str[start] = str[end]; str[end] = tmp; start++; end--; } } int main() { char str[100] = {0}; printf("请输入一个字符串:>"); scanf("%s", str); printf("原始字符串为:> %s\n", str); ReverseString(str); printf("反序字符串为:> %s\n", str); return 0; }
5、写一个函数将两个字符串连接起来
1)直接将第二个字符串加到第一个字符串后面:
#include <stdio.h> #include <string.h> int main() { void link_str(char str1[],char str2[]); char str1[20]; char str2[10]; printf("Please enter the str1:\n"); gets(str1); printf("Please enter the str1:\n"); gets(str2); link_str(str1,str2); printf("The new string is:"); puts(str1); return 0; } void link_str(char str1[],char str2[]) { int len_1=strlen(str1); // 得到两个数组的长度 int len_2=strlen(str2); for(int i=0;i<len_2;i++) // 遍历字符串数组2 { str1[len_1+i]=str2[i]; // 直接在str1接上str2 } }
2)开辟临时数组
#include<stdio.h> void ConcatStr(char string1[], char string2[], char string[]) { int i, j; for (i = 0; string1[i] != '\0'; i++) string[i] = string1[i]; // 找到字符串末尾,继续往后面链接字符串 for (j = 0; string2[j] != '\0'; j++) string[i + j] = string2[j]; string[i + j] = '\0'; // 字符串末尾加上结束符 \0 } int main() { char s1[200] = {0}, s2[100]= {0}, s[100] = {0}; printf("input string1:"); scanf("%s", s1); printf("input string2:"); scanf("%s", s2); ConcatStr(s1, s2, s); printf("\nThe new string is %s\n", s); return 0; }
6、写一个函数,将一个字符串中的元音字母复制到另一字符串,然后输出。
#include <stdio.h> void cpy(char s[], char c[]) { int i, j; for (i = 0, j = 0; s[i] != '\0'; i++) { //判断元音字母 if (s[i] == 'a' || s[i] == 'A' || s[i] == 'e' || s[i] == 'E' || s[i] == 'i' ||s[i] == 'I' || s[i] == 'o' || s[i] == 'O' || s[i] == 'u' || s[i] == 'U') { c[j] = s[i]; j++; } } c[j] = '\0'; } int main() { char str[80], c[80]; printf("input string:"); gets(str); cpy(str, c); //将str中的元音字母拷贝到c中 printf("The vowel letters are:%s\n", c); return 0; }
7、写一个函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格。如输人2020,应输出“2 0 2 0”
#include<stdio.h> void add_space(char str[]) { int i; for(i=0;str[i]!='/0';i++) { printf("%c", str[i]); if(str[i+1] == '\0') //清除最后一个空格不输出 break; printf("%c", ' '); } printf("\n"); } int main() { char str[20]={0}; scanf("%s",str); add_space(str); return 0; }
8、编写一个函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输人字符串以及输出上述的结果。
#include <stdio.h> #include <string.h> int a,n,s,o; void statistics(char str[]) { int i,len=strlen(str); for(i=0;i<len;i++) { if((str[i]>='a'&& str[i]<='z')||(str[i]>='A'&& str[i]<='Z')) { a++; } else if(str[i]>='0'&&str[i]<='9') { n++; } else if(str[i]==' ') { s++; } else { o++; } } } int main() { char str[80]; printf("Please enter a string:\n"); gets(str); statistics(str); printf("字母个数:%d\n数字个数:%d\n空格个数:%d\n其他字符:%d\n", a,n,s,o); return 0; }
9、写一个函数,输人一行字符,将此字符串中最长的单词输出。
#include <stdio.h> #include <string.h> void longest_word(char str[],char word[]) { int i,j; i=j=0; int len=0; while(str[j]!='\0') { j=i; while(str[j]!=' '&& str[j]!='\0') // 同时判断空格和字符串是否结束,后面一句是消除最后一个空格 j++; len=j-i; if(len > strlen(word)) { strncpy(word,str+i,len); // 拷贝临时最长单词 从str中的i到len个字符 } j++; i=j; } } int main() { char str[100]; char word[20]={0}; printf("Please enter a string:\n"); gets(str); longest_word(str,word); printf("%s\n",word); return 0; }
#include<stdio.h> #include<string.h> void LongestWord(char str[], char word[]) { int max_len = 0; int len = 0; int i = 0; while(str[i] != '\0') { if(str[i] == ' ') { str[i] = '\0'; len = strlen(str); if(len > max_len) { max_len = len; strcpy(word, str); str = str + len + 1; } } i++; } } int main() { char line[100] = {0}; char word[100] = {0}; printf("input one line:\n"); gets(line); LongestWord(line, word); printf("The longest word is : %s\n", word); return 0; }
10、写一个函数,用“起泡法”对输人的10个字符按由小到大顺序排列。
#include<stdio.h> #include<string.h> void BubbleSort(char str[]) { int i, j; char tmp; int len = strlen(str); for(i=0; i<len-1; ++i) { for(j=0; j<len-i-1; ++j) { if(str[j] > str[j+1]) { tmp = str[j]; str[j] = str[j+1]; str[j+1] = tmp; } } } } int main() { int i; char str[11] = {0}; printf("请输入10个字符:>"); for(i=0; i<10; ++i) scanf("%c", &str[i]); BubbleSort(str); printf("string sorted: %s\n", str); return 0; }
11、输人10个学生5门课的成绩,分别用函数实现下列功能:
① 计算每个学生的平均分;
② 计算每门课的平均分;
③ 找出所有50个分数中最高的分数所对应的学生和课程;
④ 计算平均分方差:
题目解析:
此题的关键是如何存储某个学生对应某门课程的分数,这里利用了一个二维数组score,其中score[i] [j]就代表了第i个学生的第j门课程的分数,只要能够理解这个存储方式,其余的计算就是比较容易理解和实现的。
#include<stdio.h> #define N 10 #define M 5 float score[N][M]; float a_stu[N], a_cour[M]; int r, c; void input_stu(void) // 输入学生成绩信息函数 { int i, j; for (i = 0; i < N; i++) { printf("\ninput score of student%2d:\n", i + 1); for (j = 0; j < M; j++) scanf("%f", &score[i][j]); } } void aver_stu(void) // 每个学生平均分 { int i, j; float s; for (i = 0; i < N; i++) { for (j = 0, s = 0; j < M; j++) s += score[i][j]; a_stu[i] = s / 5.0; } } void aver_cour(void) // 每门课程平均分 { int i, j; float s; for (j = 0; j < M; j++) { s = 0; for (i = 0; i < N; i++) s += score[i][j]; a_cour[j] = s / (float)N; } } float highest() // 最高分函数 { float high; int i, j; high = score[0][0]; for (i = 0; i < N; i++) for (j = 0; j<M; j++) if (score[i][j]>high) { high = score[i][j]; r = i + 1; c = j + 1; } return(high); } float s_var(void) // 方差函数 { int i; float sumx, sumxn; sumx = 0.0; sumxn = 0.0; for (i = 0; i < N; i++) { sumx += a_stu[i] * a_stu[i]; sumxn += a_stu[i]; } return(sumx / N - (sumxn / N)*(sumxn / N)); } int main() { int i, j; float h; input_stu(); aver_stu(); aver_cour(); printf("\n NO. cour1 cour2 cour3 cour4 cour5 aver\n"); for (i = 0; i < N; i++) { printf("\n NO %2d ", i + 1); for (j = 0; j < M; j++) printf("%8.2f", score[i][j]); printf("%8.2f\n", a_stu[i]); } printf("\naverage:"); for (j = 0; j < M; j++) printf("%8.2f", a_cour[j]); printf("\n"); h = highest(); printf("highest:%7.2f NO. %2d course %2d\n", h, r, c); printf("variance %8.2f\n", s_var()); return 0; }
13、输入4个整数,找出其中最大的数,用递归方法。
#include <stdio.h> int max_2(int a,int b) //找2个中最大的 { return (a>b?a:b); //注意三元式的写法 } int max_4(int x,int y,int z,int w) { return (max_2(max_2(max_2(x,y),z),w)); //递归找4个中最大的 } int main() { int a,b,c,d,max; printf("Please enter four numbers :\n"); scanf("%d,%d,%d,%d",&a,&b,&c,&d); max=max_4(a,b,c,d); printf("The max is %d\n",max); return 0; }
#include<stdio.h> int max_n(int n,int num[]); int max_2(int a, int b); int main() { int max; int num[4]; printf("Please input 4 numbers:\n"); scanf("%d %d %d %d",&num[0],&num[1],&num[2],&num[3]); max=max_n(4,num); printf("The Max is:%d\n",max); } int max_n(int n,int num[]) { int max; if(n==2) max=max_2(num[n-2],num[n-1]); else if(n>2) max=max_2(num[n-1],max_n(n-1, num)); return max; } int max_2(int a, int b) { return (a>b?a:b); }
14、用递归法将一个整数n转换成字符串。例如,输人483,应输出字符串”483”。n的位数不确定,可以是任意位数的整数。
#include<stdio.h> void Convert(int n) { int i; if ((i = n / 10) != 0) Convert(i); putchar(n % 10 + '0'); } int main() { int number; printf("input an integer: "); scanf("%d", &number); printf("output: "); if (number < 0) { putchar('-'); //先输出一个负号'-' number = -number; } Convert(number); printf("\n"); return 0; }
15、给出年、月、日,计算该日是该年的第几天。
#include <stdio.h> #include<stdio.h> /* 函数sum_day:计算日期 */ int sum_day(int month, int day) { int day_tab[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int i; for (i = 1; i < month; i++) day += day_tab[i]; /* 累加所在月之前天数 */ return day; } /* 函数leap:判断是否为闰年 */ int leap(int year) { int leap; leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; return leap; } int main() { int year, month, day, days; printf("input date(year,month,day):"); scanf("%d %d %d", &year, &month, &day); printf("%d/%d/%d ", year, month, day); days = sum_day(month, day); /* 调用函数sum_day */ if (leap(year) && month >= 3) /* 调用函数leap */ days = days + 1; printf("is the %dth day in this year.\n", days); return 0; }

浙公网安备 33010602011771号