C程序设计(第五版)-第7章 用函数实现模块化程序设计课后习题答案

1、写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输人。

题目解析:

  • 该题直接使用“辗转相除法”来求解最大公约数和最小公倍数
  • 最大公约数函数(利用欧几里得算法)
  • 最小公倍数 = x * y / 最大公约数
#include <stdio.h>
#include <windows.h>
int HCF(int x, int y); // 定义最大公约数函数
int LCM(int x, int y); // 定义最小公倍数函数
int main()
{
int a, b, hcf, lcm;
printf("请输入两个数:\n");
scanf("%d %d", &a, &b);
hcf = HCF(a, b);
lcm = LCM(a, b);
printf("最大公约数:%d,最小公倍数:%d", hcf, lcm);
return 0;
}
int HCF(int x, int y)
{
int hcf = 0;
if (y > x)
{
int temp = y;
y = x;
x = temp;
}
//1997 / 615 = 3 (余 152)
// 615 / 152 = 4(余7)
// 152 / 7 = 21(余5)
// 7 / 5 = 1 (余2)
// 5 / 2 = 2 (余1)
// 2 / 1 = 2 (余0)
// 至此,最大公约数为1
for (int z = x % y; z != 0;)
{
x = y;
y = z;
z = x % y;
}
return y;
}
int LCM(int x, int y)
{
return (x * y) / HCF(x, y);
}

2、求方程 ax^2 + b*x + c = 0的根,用3个函数分别求当: b^2 − 4ac 大于0、等于0和小于0时的根并输出结果。从主函数输入a,b,c的值。

#include <stdio.h>
#include <windows.h>
#include <math.h>
void greater_than_zero(float a, float b, float disc);
void equal_to_zero(float a, float b);
void smaller_than_zero(float a, float b, float disc);
// 请输入a,b,c:
// 3 4 1
// b^2-4ac=4.000000
// x1 = -0.333333, x2 = -1.000000
int main()
{
float a, b, c, disc;
printf("请输入a,b,c:\n");
scanf("%f %f %f", &a, &b, &c);
disc = pow(b, 2) - (4 * a * c);
printf("b^2-4ac=%f\n", disc);
if (disc > 0)
{
greater_than_zero(a, b, disc);
}
else if (disc == 0)
{
equal_to_zero(a, b);
}
else if (disc < 0)
{
smaller_than_zero(a, b, disc);
}
return 0;
}
void greater_than_zero(float a, float b, float disc)
{
float x1, x2;
x1 = (-b + sqrt(disc)) / (2 * a);
x2 = (-b - sqrt(disc)) / (2 * a);
printf("x1 = %f, x2 = %f\n", x1, x2);
}
void equal_to_zero(float a, float b)
{
float x;
x = (-b) / (2 * a);
printf("x1 = x2 = %f\n", x);
}
void smaller_than_zero(float a, float b, float disc)
{
float x1, x2;
x1 = (-b + sqrt(disc)) / (2 * a);
x2 = (-b - sqrt(disc)) / (2 * a);
printf("x1 = %f, x2 = %f\n", x1, x2);
}

3、写一个判素数的函数,在主函数输人一个整数,输出是否为素数的信息。

  • 素数是一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做素数
  • 该题可以使用概念直接判断法求解,不过不需要判断所有的数据,只需要判断数据的一半即可,因为偶数不可能为素数(除了2),所以只需判断该数的一半即可的到答案
#include <stdio.h>
#include <windows.h>
void isAPrimeNumber(int x);
int main()
{
int x;
do
{
printf("请输入一个整数\n");
scanf("%d", &x);
} while (x <= 1);
isAPrimeNumber(x);
return 0;
}
void isAPrimeNumber(int x)
{
int flag = 1; // 1代表是 0代表false
for (int i = 2; i <= x / 2; i++)
{
if (x % i == 0)
{
flag = 0;
break;
}
}
if (flag)
{
printf("%d是素数\n", x);
}
else
{
printf("%d不是素数\n", x);
}
}

4、写一个函数,使给定的一个3X3的二维整型数组转置,即行列互换。

#include <stdio.h>
#include <windows.h>
void PrintArray(int ar[3][3]);
void ReverseArray(int ar[3][3]);
int main()
{
printf("------------------\n");
int a[3][3] = {
{0, 1, 2},
{3, 4, 5},
{6, 7, 8}
};
printf("---------前---------\n");
PrintArray(a);
printf("---------后---------\n");
ReverseArray(a);
return 0;
}
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 result[3][3];
for (int i = 0; i < 3; i++){
for (int j = 0; j < 3; j++){
result[i][j] = ar[j][i];
}
}
PrintArray(result);
}

5、写一个函数,使输人的一个字符串按反序存放,在主函数中输入和输出字符串。

题目解析及答案:

  • 要把一个字符串反序存放,其实就是对字符串做一个逆序操作,操作过程为收尾字符交换,直到把所有字符全部交换完毕。
#include <stdio.h>
#include <windows.h>
void reverseChar(char a[]);
int main()
{
printf("-------请输入10个字符串-----------\n");
char a[10];
scanf("%s", a);
printf("-------前-----------\n");
printf("%s\n", a);
reverseChar(a);
printf("-------后-----------\n");
puts(a);
return 0;
}
void reverseChar(char a[])
{
int start = 0;
int end = strlen(a) - 1; // 数组下表从0开始
while (end > start)
{
char temp = a[end];
a[end] = a[start];
a[start] = temp;
start++;
end--;
}
}

6、写一个函数,将两个字符串连接。

题目解析及答案:

  • 利用一个临时数组,空间要保证能够容纳两个字符串,先把第一个字符串进行拷贝到临时数组,第二个字符串在临时数组的尾部接着链接,最后记得加上字符串的结束标记\0即可
#include <stdio.h>
#include <windows.h>
void cat(char a[], char b[], char c[]);
int main()
{
printf("------------------\n");
char a[10], b[10], c[20];
printf("输入a字符串:\n");
gets(a);
printf("输入b字符串:\n");
scanf("%s", &b);
cat(a, b, c);
return 0;
}
void cat(char a[], char b[], char c[])
{
int j = 0;
for (int i = 0; i < strlen(a) & a[i] != '\0'; i++, j++)
{
c[j] = a[i];
}
for (int i = 0; i < strlen(b) & b[i] != '\0'; i++, j++)
{
c[j] = b[i];
}
c[j + 1] = '\0';
puts(c);
}

7、写一个函数,将一个字符串中的元音字母复制到另一字符串,然后输出。

#include <stdio.h>
#include <windows.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;
}

8、写一个函数,输人一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格。如输人1990,应输出“1 9 9 0”。

#include <stdio.h>
#include <windows.h>
void OutString(char str[]);
int main()
{
printf("------------------\n");
char str[5] = {0};
printf("input four digits:");
scanf("%s", str);
OutString(str);
return 0;
}
void OutString(char str[])
{
for (int i = 0; i < strlen(str); i++)
{
printf("%c", str[i]);
// 最后一个不输出-
if (i == strlen(str) - 1)
{
break;
}
else
{
printf("-");
}
}
}

9、编写一个函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输人字符串以及输出上述的结果。

#include <stdio.h>
#include <windows.h>
void statisticsStrCount(char a[]);
int main()
{
char a[100];
printf("请输入一cuan字符串\n");
gets(a);
statisticsStrCount(a);
return 0;
}
void statisticsStrCount(char a[])
{
int alphabet_count = 0, number_count = 0, blank_count = 0, other_count = 0;
for (int i = 0; i < 100 & a[i] != '\0'; i++)
{
if ((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && a[i] <= 'Z'))
{
alphabet_count++;
}
else if ((a[i] >= '0' && a[i] <= '9'))
{
number_count++;
}
else if (a[i] = ' ')
{
blank_count++;
}
else
{
other_count++;
}
}
printf("字母:%d个,数字:%d个,空格:%d个,其它:%d个", alphabet_count, number_count, blank_count, other_count);
}

10、写一个函数,输人一行字符,将此字符串中最长的单词输出。

题目解析及答案:

单词以空格进行分隔,因此寻找空格出现的位置即为关键,每次从单词的起始到空格出现的位置即为一个单词,此时计算单词的长度,如果比当前最大的还长,就进行跟新最长单词信息,当整个字符串遍历完成,word即保存最长字符串。

#include <stdio.h>
#include <windows.h>
void statisticsMaxStr(char a[]);
int main()
{
char a[100];
printf("请输入一段英文\n");
gets(a);
statisticsMaxStr(a);
return 0;
}
void statisticsMaxStr(char a[])
{
char maxStr[50];
int maxStrCount = 0, currentCount = 0;
int minIndex = 0, maxIndex = 0, i;
for (i = 0; i < 100 & a[i] != '\0'; i++)
{
currentCount++;
// 碰到空格,将计数器赋值为0
if (a[i] == ' ')
{
if (currentCount >= maxStrCount)
{
maxStrCount = currentCount;
maxIndex = i;
minIndex = i + 1 - currentCount;
}
currentCount = 0;
}
}
if (currentCount >= maxStrCount) //此乃用于最长的单词在结尾的情况
{
maxStrCount = currentCount;
maxIndex = i;
minIndex = i + 1 - currentCount;
}
for (int i = minIndex; i < maxIndex; i++)
{
printf("%c", a[i]);
}
}

11、写一个函数,用“起泡法”对输人的10个字符按由小到大顺序排列。

#include <stdio.h>
#include <windows.h>
void sortChar(char a[]);
int main()
{
char a[10];
printf("请输入10个字符:");
gets(a);
sortChar(a);
return 0;
}
void sortChar(char a[])
{
for (int i = 0; i < strlen(a)-1; i++)
{
for (int j = 0; j < strlen(a) - i - 1; j++)
{
if (a[j + 1] < a[j])
{
char temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
puts(a);
}

12、用牛顿迭代法求根。方程为ax3+bx2 +cx+d=0, 系数a,b,c,d的值依次为1,2,3,4,由主函数输人。求x在1附近的一个实根。求出根后由主函数输出。

题目解析及答案:

此题的难点并不是编程,主要是要理解数学公式的求解方法,理解之后代码的实现并不困难。

#include<stdio.h>
#include<math.h>
float solut(int a, int b, int c, int d)
{
float x = 1, x0, f, f1;
do
{
x0 = x;
f = ((a*x0 + b)*x0 + c)*x0 + d;
f1 = (3 * a*x0 + 2 * b)*x0 + c;
x = x0 - f / f1;
} while (fabs(x - x0) >= 1e-3);
return(x);
}
int main()
{
int a, b, c, d;
printf("input a,b,c,d:");
scanf("%d %d %d %d", &a, &b, &c, &d);
printf("x=%10.7f\n", solut(a, b, c, d));
return 0;
}

13.用递归方法求n阶勒让德多项式的值,递归公式为

image-20220112112759382

  • 递归函数的设计,有一个点非常重要,那就是必须要有返回条件,,此题中的返回条件即为n0和n1时,因为当n为这两值时,程序直接返回相应的值,只有n>=1时,才进行递归运算。
#include<stdio.h>
double polya(int n,int x)
{
double result;
if(n == 0)
result = 1;
if(n == 1)
result = x;
if(n>1)
result = ((2*n-1)*x*polya(n-1,x)-(n-1)*polya(n-2,x))/n;
return result;
}
int main()
{
int x,n;
scanf("%d %d", &n, &x);
printf("%.2f\n", polya(n,x));
return 0;
}

14、输人10个学生5门课的成绩,分别用函数实现下列功能:

①计算每个学生的平均分;
②计算每门课的平均分;
③找出所有50个分数中最高的分数所对应的学生和课程;
④计算平均分方差:

其中,x;为某一学生的平均分。

题目解析及答案:
此题的关键是如何存储某个学生对应某门课程的分数,这里利用了一个二维数组score,其中score[i] [j]就代表了第i个学生的第j门课程的分数,只要能够理解这个存储方式,其余的计算就是比较容易理解和实现的。

#include <stdio.h>
#include <windows.h>
#define M 10
#define N 5
void studentAverageScore(float a[M][N]); // 计算每个学生的平均分
void scourseAverageScore(float a[M][N]); // 计算每门课的平均分
void studentMaxScoreAndScore(float a[M][N]); // 找出所有50个分数中最高的分数所对应的学生和课程
float studentAverageScoreVariance(float a[M][N]); // 计算平均分方差
float a[M][N];
float a_stu[M], a_cour[N];
int main()
{
printf("输入分数\n");
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
scanf("%f", &a[i][j]);
}
}
studentAverageScore(a);
scourseAverageScore(a);
studentMaxScoreAndScore(a);
studentAverageScoreVariance(a);
return 0;
}
void studentAverageScore(float a[M][N])
{
for (int i = 0; i < M; i++)
{
float totalScore = 0;
for (int j = 0; j < N; j++)
{
totalScore += a[i][j];
}
a_stu[i] = totalScore / 5.0;
printf("第%d个学生平均成绩:%f", i, totalScore / N);
}
}
void scourseAverageScore(float a[M][N])
{
for (int i = 0; i < N; i++)
{
float totalScore = 0;
for (int j = 0; j < M; j++)
{
totalScore += a[j][i];
}
a_cour[i] = totalScore / (float)M;
printf("第%d门课程平均成绩:%f", i, totalScore / M);
}
}
void studentMaxScoreAndScore(float a[M][N])
{
int x, y;
int maxScore = 0;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
if (a[i][j] >= maxScore)
{
maxScore = a[i][j];
x = i;
y = j;
}
}
printf("第%d个学生的%d课程成绩最好", x, y);
}
}
float studentAverageScoreVariance(float a[M][N])
{
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));
}

15、写几个函数:

①输人10个职工的姓名和职工号;
②按职工号由小到大顺序排序,姓名顺序也随之调整;
③要求输人一个职工号,用折半查找法找出该职工的姓名,从主函数输人要查找的职工号,输出该职工姓名。

题目解析及答案:
利用二分查找的关键在于数据一定要先有序,所以在查找前我们需要对数据进行排序。

#include <stdio.h>
#include <windows.h>
#define N 4
struct Employee // 职工结构体
{
int id; // 职工编号
char name[20]; // 职工姓名
};
void inputEmployee(struct Employee e[N]);
void sortEmployee(struct Employee e[N]);
void searchEmployee(struct Employee e[N], int id);
main()
{
printf("------------------\n");
int id;
struct Employee employeeAry[N]; //创建N个结构体数组
inputEmployee(employeeAry);
sortEmployee(employeeAry);
printf("请输入要查找的员工编号:");
scanf("%d", &id);
searchEmployee(employeeAry, id);
return 0;
}
void inputEmployee(struct Employee e[N])
{
for (int i = 0; i < N; i++)
{
printf("请输入第%d个员工编号:", i);
scanf("%d", &e[i].id);
printf("请输入第%d个员工姓名:", i);
scanf("%s", &e[i].name);
printf("\n");
}
}
void sortEmployee(struct Employee e[N])
{
// 冒泡排序法
for (int i = 0; i < N - 1; i++)
{
for (int j = 0; j < N - 1 - i; j++)
{
if (e[j + 1].id < e[j].id)
{
struct Employee temp;
temp.id = e[j + 1].id;
strcpy(temp.name, e[j + 1].name);
e[j + 1].id = e[j].id;
strcpy(e[j + 1].name, e[j].name);
e[j].id = temp.id;
strcpy(e[j].name, temp.name);
}
}
}
}
void searchEmployee(struct Employee e[N], int id)
{
int mid, min, max, flag;
min = 0;
max = N - 1;
flag = 0; // 没有该编号员工
// 二分查找
while (min <= max)
{
mid = (min + max) / 2;
if (e[mid].id > id)
{
max = mid - 1;
}
else if (e[mid].id < id)
{
min = mid + 1;
}
else if (e[mid].id = id)
{
printf("编号%d的员工姓名是:%s", id, e[mid].name);
flag = 1;
return;
}
}
if (flag == 0)
{
printf("编号%d的员工不存在", id);
}
}

16、写一个函数,输人一个十六进制数,输出相应的十进制数。

题目解析及答案:

  • 转换的过程需要乘的基数为16,其次注意十六进制中的a~f的字母转换,并且无论大小写都要能够转换。
#include <stdio.h>
#include <windows.h>
#include <math.h>
void HextoDec(char a[]);
int main()
{
char a[20];
// 十六进制整常数的前缀为0X或0x
printf("输入一个十六进制数:");
gets(a);
HextoDec(a);
return 0;
}
// 例:2AF5换算成10进制:
// 用竖式计算:
// 第0位: 5 * 16^0 = 5
// 第1位: F * 16^1 = 240
// 第2位: A * 16^2= 2560
// 第3位: 2 * 16^3 = 8192
// -------------------------------------
// 10997
// 直接计算就是:
// 5 * 16^0 + F * 16^1 + A * 16^2 + 2 * 16^3 = 10997
void HextoDec(char a[])
{
int result = 0;
for (int i = 0, j = strlen(a) - 1; i < strlen(a); i++, j--)
{
if (a[i] == 'A' || a[i] == 'a')
{
result += (10 * pow(16, j));
}
else if (a[i] == 'B' || a[i] == 'b')
{
result += (11 * pow(16, j));
}
else if (a[i] == 'C' || a[i] == 'c')
{
result += (12 * pow(16, j));
}
else if (a[i] == 'D' || a[i] == 'd')
{
result += (13 * pow(16, j));
}
else if (a[i] == 'E' || a[i] == 'e')
{
result += (14 * pow(16, j));
}
else if (a[i] == 'F' || a[i] == 'f')
{
result += (15 * pow(16, j));
}
else
{
// ASCII码为0时,ASCII码对应48,所以(对应数字 = ASCII码- 48)
result += ((a[i] - 48) * pow(16, j));
}
}
printf("十六进制%s的二进制是:%d", a, result);
}

17、用递归法将一个整数n转换成字符串。例如,输人483,应输出字符串”483”。n的位数不确定,可以是任意位数的整数。

题目解析及答案:

  • 递归法求解主要要有结束条件,此题为n/10 == 0时就直接输出,其次本题还要考虑如果整数位负数的情形,此时需要输出一个字符串的负号。
#include <stdio.h>
#include <windows.h>
void convert(int number);
int main()
{
int number;
printf("请输入一个整数\n");
scanf("%d", &number);
if (number < 0)
{
putchar('-');
number = -number;
}
convert(number);
return 0;
}
void convert(int number)
{
int i;
if ((i = number / 10) != 0)
{
convert(i);
}
putchar(number % 10 + '0');
}

18、给出年、月、日,计算该日是该年的第几天。

题目解析:

  • 此题采用枚举法进行每月天数的累加,其中关键点注意需要判断年份是否为闰年,如果是还需要多累加1天。
#include <stdio.h>
#include <windows.h>
int sumDay(int month, int day); // 计算日子
int leap(int year); // 是否是闰年,闰年返回1,不是返回0
// 请输入年,月,日:
// 2020 6 24
// 2020-6-24是今年的第176天
int main()
{
int year, month, day;
printf("请输入年,月,日:\n");
scanf("%d %d %d", &year, &month, &day);
int sumDayCount = sumDay(month, day);
int leapCount = leap(year);
int total = sumDayCount + leapCount;
printf("%d-%d-%d是今年的第%d天", year, month, day, total);
return 0;
}
int sumDay(int month, int day)
{
int sumDayCount = 0;
int monthlyDay[13] = {0,
31,
28,
31,
30,
31,
30,
31,
31,
30,
31,
30,
31};
for (int i = 1; i < month; i++)
{
sumDayCount += monthlyDay[i];
}
sumDayCount += day;
return sumDayCount;
}
int leap(int year)
{
int leapCount;
leapCount = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
return leapCount;
}

C程序设计(第五版)-第1章 程序设计和C语言课后习题答案
C程序设计(第五版)-第2章 算法--程序的灵魂课后习题答案
C程序设计(第五版)-第3章 最简单的C程序设计—顺序程序设计课后习题答案
C程序设计(第五版)-第4章 选择结构程序设计课后习题答案
C程序设计(第五版)-第5章 循环结构程序设计课后习题答案
C程序设计(第五版)-第6章 利用数组处理批量数据课后习题答案
C程序设计(第五版)-第7章 用函数实现模块化程序设计课后习题答案

posted @   luckyangg  阅读(634)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
· 易语言 —— 开山篇
点击右上角即可分享
微信分享提示