《C语言程序设计教程》(主编黄迪明、余勤)第六章课后习题答案

       在阅读代码前,先说一下这本书的在版编目(CIP)数据:C语言程序设计教程/黄迪明、余勤主编.--北京:国防工业出版社,2006.5    ISBN 7-118-04516-0

       所有代码均在 VS2013 中成功运行。第一次写博客,若有不妥之处,非常欢迎您提出问题,若能提出改进意见,不胜感激!



6.1  写一个函数,使其能将一个二维数组(5*3)中的数据进行行列互换。

#include 
#include
void main()
{
	printf(" 写一个函数,使其能将一个二维数组(5*3)中的数据进行行列互换。\n\n");
	int nrows = 0, ncolumns = 0;
	int i, l;
	printf("请输入数组的行数:");
	scanf("%d", &nrows);
	printf("请输入数组的列数:");
	scanf("%d", &ncolumns);
	//为输入的数组分配行数    
	int **array1 = malloc(nrows * sizeof(*array1));//注意分配的是整形指针的数量 每行元素是个整形指针
	//对每行分配数组个数(就是二维数组的列数)
	for (i = 0; i < nrows; i++)
	{
		printf("数组第 %d 行的数分别为:", i + 1);
		array1[i] = (int*)malloc(ncolumns * sizeof(int));
		for (l = 0; l


6.2  写一个函数,使其能通过主调函数通过实参传来的字符串,对其中的字母、空格、数字分别计数(要求在主函数中输入字符串及统计结果)。

#include
int countchr(char* str);
int countspace(char* str);
int countnumber(char* str);
void output(int chr, int number, int space);
int countchr(char* str)
{
	int chr = 0;
	while (*str!='\0')
	{
		if ((*str >= 'a'&&*str <= 'z') || (*str >= 'A'&&*str <= 'Z'))
		{
			chr = chr + 1;
		}
		str++;
	}
	return chr;
};
int countspace(char* str)
{
	int chr = 0;
	while (*str != '\0')
	{
		if (*str==' ')
		{
			chr = chr + 1;
		}
		str++;
	}
	return chr;
};
int countnumber(char* str)
{
	int chr = 0;
	while (*str != '\0')
	{
		if (*str >= '0'&&*str <= '9')
		{
			chr = chr + 1;
		}
		str++;
	}
	return chr;
};
void output(int chr, int number, int space)
{
	printf("\n字符串中字母的个数为:%d",chr);
	printf("\n字符串中数字的个数为:%d", number);
	printf("\n字符串中字母的个数为:%d", space);
};
void main()
{
	printf("写一个函数,使其能通过主调函数通过实参传来的字符串,对其中的字母、空格、数字分别计数(要求在主函数中输入字符串及统计结果)。");
	char c[100];
	printf("请输入一个字符串:");
	gets(c);
	int chr = 0, number = 0, space = 0;
	char *str = &c;
	chr = countchr(str);
	number = countnumber(str);
	space = countspace(str);
	output(chr,number,space);
	getch();
}


6.3  写一个函数,使其能处理字符串中除字母(大小写)、数字外的其他ASCII码,对多余一个连在一起的相同字符,使其缩减至仅保留一个。

#include
void chr(char* str1, char* str2);
void output(char* str2);
void chr(char* str1, char* str2)
{
	int k = 0;
	while (*str1 != '\0')
	{
		if ((*str1 >= 'a'&&*str1 <= 'z') || (*str1 >= 'A'&&*str1 <= 'Z') || (*str1 >= '0'&&*str1 <= '9'))
		{
			k = 0;
			*str2 = *str1;
			str2++;
		}
		else
		{
			if (k != 1)
			{
				k = 1;
				*str2 = *str1;
			}
		}
		str1++;
	}
}
void output(char* str2)
{
	printf("转换后的字符串为:");
	while (*str2 != '\0')
	{
		printf("%c", *str2);
		str2++;
	}
}

void main()
{
	printf("写一个函数,使其能处理字符串中除字母(大小写)、数字外的其他ASCII码,对多余一个连在一起的相同字符,使其缩减至仅保留一个。");
	char c1[100] = { '\0' };
	char c2[100] = { '\0' };
	char *str2 = &c2[0];
	printf("请输入一个字符串:");
	gets(c1);
	char *str1 = &c1[0];
	chr(str1, str2);
	str2 = &c2[0];
	output(str2);
	getch();
}



6.4  设有一个三位数,使其百、十、个三个数,各自求立方,然后加起来正好等于这个三位数。例如151=1^3+5^3+1^3。写一个函数,找出所有满足条件的数。

#include
void find(int n);
void find(int n1,int n2)
{
	int n,k=0;
	for (n= n1;n<=n2; n++)
	{
		int a = 0, b = 0, c = 0, sum = 0;
		a = n % 100;
		b = n % 100 / 10;
		c = n / 100;
		sum = a*a*a + b*b*b + c*c*c;
		if (sum == n)
		{
			printf("%4d", n);
			k = k + 1;
			if (k%5==0)
			{
				printf("\n");
			}
		}
	}
};
void main()
{
	printf(" 设有一个三位数,使其百、十、个三个数,各自求立方,然后加起来正好等于这个三位数。例如151=1^3+5^3+1^3。找出所有满足条件的数。\n\n");
	int n1=0,n2=0;
	printf("请输入要查找完数范围的下限:");
	scanf("%d",&n1);
	printf("请输入要查找完数范围的上限:");
	scanf("%d",&n2);
	find(n1, n2);
	getch();
}


6.5  写一个函数,使其能求出一元二次方程的解。

#include
#include
void judge(float a,float b,float c);
float pf1(float a, float b, float c);
float pf2(float a, float b, float c);
void judge(float a, float b, float c)
{
	float an1, an2;
	if (b*b-4*a*c<0)
	{
		printf("该一元二次方程无解!");
	}
	else
	{
		an1 = pf1(a, b, c);
		an2 = pf2(a, b, c);
		if (an1==an2)
		{
			printf("该方程的解为:%f",an1);
		}
		else
		{
			printf("\n该方程的一个解为:%f\n", an1);
			printf("\n该方程的另一个解为:%f\n", an2);
		}
	}
}
float pf1(float a, float b, float c)
{
	float n;
	n = (-b + sqrt(b*b - 4 * a*c) / 2);
	return n;
}
float pf2(float a, float b, float c)
{
	float n;
	n = (-b - sqrt(b*b - 4 * a*c) / 2);
	return n;
}

void main()
{
	printf("写一个函数,使其能求出一元二次方程的解。\n\n");
	float a, b, c;
	printf("请输入该一元二次方程的二次项系数:");
	scanf("%f",&a);
	printf("请输入该一元二次方程的一次项系数:");
	scanf("%f", &b);

	printf("请输入该一元二次方程的常数项:");
	scanf("%f", &c);
	judge(a, b, c);
	getch();
}


6.6  写一个函数,从键盘输入5个正整数,然后求出他们的最小公倍数,并输出(通过调用对两个数求最小公倍数的函数实现)。

#include
int maxyue(int a, int b);
int minbei(int a, int b);
int maxyue(int a, int b)
{
	if (a % b == 0)
	{
		return b;
	}
	else
	{
		maxyue(b, a % b);
	}
};
int minbei(int a, int b)
{
	return a*b / (maxyue(a, b));
};
void main()
{
	printf("写一个函数,从键盘输入5个正整数,然后求出他们的最小公倍数,并输出\n\n");
	int a1, a2, a3, a4, a5;
	int n;
	printf("请输入五个正整数:");
	scanf("%d%d%d%d%d", &a1, &a2, &a3, &a4, &a5);
	n = minbei(a1, a2);
	n = minbei(n, a3);
	n = minbei(n, a4);
	n = minbei(n, a5);
	printf("这五个正整数的最小公倍数是:%d", n);
	getch();
}


6.7  如果一个数正好是他所有约数(除他本身以外)的和,称此数为完备数。如6,他的约数有1,2,3,,并且1+2+3=6.求出30000以内所有的完备数,并输出。(求完备数用函数实现)

#include
#include
void find(int n);
void find(int n)
{
	int i = 0, k = 1;
	for (i = 4; i <= n; i++)
	{
		int j = 0, m = 1;
		int *temp;
		temp = (int*)malloc(sizeof(int)*i);
		for (m = 1; m <= i / 2; m++)
		{
			if (i % m == 0)
			{
				temp[j] = m;
				j = j + 1;
			}
		}
		int t = 0, sum = 0;
		for (t = 0; t < j; t++)
		{
			sum = sum + temp[t];
		}
		if (sum == i)
		{
			printf("%6d", i);
			k = k + 1;
		}
		if (k % 6 == 0)
		{
			printf("\n");
		}
		free(temp);
	}
}
void main()
{
	printf("如果一个数正好是他所有约数(除他本身以外)的和,称此数为完备数。如6,他的约数有1,2,3,,并且1+2+3=6.求出30000以内所有的完备数,并输出。");
	int n = 0;
	printf("请输入查找完备数的上限:");
	scanf("%d", &n);
	find(n);
	getch();
}


6.8  如果有两个数,每个数所有约数(除他本身)的和正好等于对方,则称这两个数为互满数。求出30000以内所有的互满数,并显示输出。求一个数所有的约数(除他本身)的和用函数实现。

#include
#define N 30000 
int yueshu(int n);
int yueshu(int n)
{
	int j = 0, m = 1;
	int *temp;
	temp = (int*)malloc(sizeof(int)*n);
	for (m = 1; m <= n / 2; m++)
	{
		if (n%m == 0)
		{
			temp[j] = m;
			j = j + 1;
		}
	}
	int t = 0, sum = 0;
	for (t = 0; t < j; t++)
	{
		sum = sum + temp[t];
	}
	free(temp);
	return sum;
}
void main()
{
	int c1[30001] = { 0 }, c2[30001] = { 0 };
	int i = 0, k = 0, j = 0;
	for (i = 1; i <= N; i++)
	{
		c1[i] = i;
	}
	for (i = 1; i <= N; i++)
	{
		c2[i] = yueshu(i);
	}
	printf("30 000以内所有的互满数有:");
	for (i = 2; i <= N; i++)
	{
		if (c2[i] != 0)
		{
			int a = 1;
			for (j = i + 1; j <= N; j++)
			{
				if (c2[i] == c2[j])
				{
					printf("%6d", c1[j]);
					c2[j] = 0;
					a = a + 1;
					k = 1;
					if (a % 5 == 0)
					{
						printf("\n");
					}
				}
			}
			if (k == 1)
			{
				printf("%6d", c1[i]);
				c2[i] = 0;
				printf("上述的数为互满数.\n");
			}
			k = 0;
		}
	}
	getch();
}


6.9  用函数实现将一组输入的数据逆序输出。

#include
void isort(int n);
void isort(int n)
{
	int *c1;
	c1 = (int*)malloc(sizeof(int)*n);
	int i = 1, k = 0;
	for (; i <= n; i++)
	{
		printf("请输入第 %d 个数:",i);
		scanf("%d",&c1[i-1]);
	}
	for ( i = n; i >= 1; i--)
	{
		printf("%6d",c1[i-1]);
		k = k + 1;
		if (k%5==0)
		{
			printf("\n");
		}
	}
	free(c1);
}
void main()
{
	printf("  用函数实现将一组输入的数据逆序输出。\n\n");
	int n = 0;
	printf("请输入数组中数据的个数:");
	scanf("%d",&n);
	isort(n);
	getch();
}


6.10  有一个数组,内放10个整数,要求编写一函数求出最小的数及其下标。

#include
void isort(int n);
void isort(int n)
{
	int *c1;
	c1 = (int*)malloc(sizeof(int)*(n+1));
	int i = 1, k = 0;
	for (; i <= n; i++)
	{
		printf("请输入第 %d 个数:", i);
		scanf("%d", &c1[i]);
	}
	int min = 0;
	min = c1[1];
	for ( i = 1; i <= n; i++)
	{
		if (c1[i]


6.11  编写一函数,实现将两个字符串比较大小(不用标准库函数)。

#include
int cmp(char s1[], char s2[]);
int cmp(char s1[], char s2[])
{
	int len1 = 0, len2 = 0, i = 0,c=0,k=0;
	len1 = strlen(s1);
	len2 = strlen(s2);
	c = len1 - len2;
	if (c>0)
	{
		for ( i = 0; i < len1; i++)
		{
			if (s1[i]-s2[i]>0)
			{
				printf("较大的字符串为:%s",s1);
				break;
			}
		}
	}
	else if (c<0)
	{
		for (i = 0; i < len2; i++)
		{
			if (s2[i] - s1[i]>0)
			{
				printf("较大的字符串为:%s", s1);
				break;
			}
		}
	}
	else
	{
		for (i = 0; i < len1; i++)
		{
			if (s1[i] - s2[i]>0)
			{
				printf("较大的字符串为:%s", s1);
				k = 1;
				if (k == 0)
				{
					printf("两个字符串一样大.");
				}
				break;
			}
		}
	}
	getch();
}
void main()
{
	printf("编写一函数,实现将两个字符串比较大小(不用标准库函数)。\n\n");
	char s1[100] = { '\0' }, s2[100] = { '\0' };
	printf("请输入第一个字符串:");
	gets(s1);
	printf("请输入第二个字符串:");
	gets(s2);
	cmp(s1, s2);
	getch();
}


6.12  编写一函数,实现两个字符串的复制。

#include
void copy(char s1[], char s2[]);
void copy(char s1[], char s2[])
{
	int len = 0, i = 0;
	len = strlen(s2);
	for ( i = 0; i <= len; i++)
	{
		s1[i] = s2[i];
	}
}
void main()
{
	printf("编写一函数,实现两个字符串的复制。\n\n");
	char s1[100], s2[100];
	printf("请输入第一个字符串:");
	gets(s1);
	printf("请输入第二个字符串:");
	gets(s2);
	copy(s1, s2);
	printf("复制后第一个字符串为:"):
	puts(s1);
	getch();
}


6.13  从键盘输入10名学生的成绩,显示其中的最低分、最高分及平均成绩。求最高分、最低分及平均成绩用子函数实现。

#include
#include
void student(int n);
void student(int n)
{
	struct date
	{
		int year;
		int month;
		int day;
	};
	struct stu
	{
		char name[21];
		int sex;
		struct date birthday;
		float height;
		int cyuyan;
		int weijifen;
	};
	struct stu *pt;
	pt = (struct stu*)malloc(sizeof(struct stu)*(n + 1));
	int i = 0;
	int weisum = 0, weihei, weilow;
	int csum = 0, chei, clow;
	float weiave = 0, cave = 0;
	for (i = 1; i <= n; i++)
	{
		printf("\n请输入第%d个学生的信息", i);
		printf("\n姓名:");
		scanf("%s", &pt[i].name);
		printf("\n性别(0男 1女):");
		scanf("%d", &pt[i].sex);
		printf("\n出生年龄\n");
		printf("年份:");
		scanf("%d", &pt[i].birthday.year);
		printf("月份:");
		scanf("%d", &pt[i].birthday.month);
		printf("日期:");
		scanf("%d", &pt[i].birthday.day);
		printf("身高(cm):");
		scanf("%f", &pt[i].height);
		printf("C语言成绩:");
		scanf("%d", &pt[i].cyuyan);
		printf("微积分成绩:");
		scanf("%d", &pt[i].weijifen);
	}
	weihei = pt[1].weijifen;
	weilow = pt[1].weijifen;
	chei = pt[1].cyuyan;
	clow = pt[1].cyuyan;
	for (i = 1; i <= n; i++)
	{
		if (cheipt[i].cyuyan)
		{
			clow = pt[i].cyuyan;
		}
		csum = csum + pt[i].cyuyan;
		if (weiheipt[i].weijifen)
		{
			weilow = pt[i].weijifen;
		}
		weisum = weisum + pt[i].weijifen;
	}
	cave = (float)csum / n;
	weiave = (float)weisum / n;
	printf("C语言课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", cave, chei, clow);
	printf("获得C语言最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (chei == pt[i].cyuyan)
		{
			printf("%s\n", pt[i].name);
		}
	}
	printf("微积分课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", weiave, weihei, weilow);
	printf("获得微积分最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (weihei == pt[i].weijifen)
		{
			printf("%s\n", pt[i].name);
		}
	}
}

void main()
{
	printf("从键盘输入10名学生的成绩,显示其中的最低分、最高分及平均成绩。求最高分、最低分及平均成绩用子函数实现。\n\n");
	int n = 0;
	printf("请输入学生的人数:");
	scanf("%d", &n);
	student(n);
	getch();
}


6.14  在总数为n的对象中,任意取p个不同的组合,可以用C(p,n)来表示,其中p≤n。写一个程序,在给出n和p的情况下,计算并输出结果。(能输出具体的组合更好)

#include
int flo(int n,int p);
int flo(int n,int p)
{
	int sum1 = 1, sum2 = 1, sum3 = 1,i=1,c=0;
	for ( i = 1; i <= n; i++)
	{
		sum1 = sum1*i;
	}
	for (i = 1; i <= p; i++)
	{
		sum2 = sum2*i;
	}
	for (i = 1; i <= (n-p); i++)
	{
		sum3 = sum3*i;
	}
	c = sum1 / (sum2 + sum3);
	return c;
}
void main()
{
	printf("在总数为n的对象中,任意取p个不同的组合,可以用C(p,n)来表示,其中p≤n。\n写一个程序,在给出n和p的情况下,计算并输出结果。(能输出具体的组合更好)\n\n");
	int n = 0, p = 0;
	printf("请输入组合的总数:");
	scanf("%d",&n);
	printf("请输入组合的个数:");
	scanf("%d",&p);
	printf("组合的种类有:%d",flo(n,p));
	getch();
}


6.15  定义函数判断一个点与坐标原点的距离是否小于1,是否在单位圆内。写一个通过蒙特卡罗方法计算圆周率值的程序:每次计算随机生成的两个数(利用标准库函数实现生成随机数),看这两个数形成的点是否在单位圆内。生成一系列随机点,统计单位圆内与圆外的点的4倍是否趋向于π值。生成100,200,...,1000个随机点做实验。

#include
#include
#include
#define RAND_MAX 0x7fff 
float pi(int n);
float pi(int n)
{
	int i = 0;
	float m = 0, c = 0, x = 0, y = 0;
	for (i = 1; i <= n; i++)
	{
		x = rand() / (RAND_MAX + 1.0);
		y = rand() / (RAND_MAX + 1.0);
		if (x*x + y*y < 1)
		{
			c = c + 1;
		}
	}
	m = c / n * 4;
	return m;
}
void main()
{
	printf("定义函数判断一个点与坐标原点的距离是否小于1,是否在单位圆内。写一个通过蒙特卡罗方法计算圆周率值的程序:\n每次计算随机生成的两个数(利用标准库函数实现生成随机数),看这两个数形成的点是否在单位圆内。生成一系列随机点,\n统计单位圆内与圆外的点的4倍是否趋向于π值。生成100,200,...,1000个随机点做实验。\n\n");
	srand((unsigned)time(NULL));
	int n;
	printf("请输入生成的个数:");
	scanf("%d", &n);
	printf("这两个值生成的点在单位圆内与圆外之比的四倍为:%f", pi(n));
	getch();
}


6.16  请实现一函数,使他能求出一个定义好的数学函数在某一区间的数值积分值。试采用矩形方法、梯形方法,考察他们在不同的情况下,加细分割对积分值的影响。用不同的函数试验程序。(如果函数在积分区间内出现奇点,程序会出现什么问题?怎么办?个人认为情况比较多,该步骤在代码中未给出)

#include
#define low 0.0
#define hei 2.0
#define a 1
#define b 2
#define c 3
#define ju len*(a*x*x+b*x+c)
#define ti len*(a*x*x+b*x+c+a*(x+len)*(x+len)+b*(x+len)+c)/2
float jf(int n);
float jf(int n)
{
	float len = 0, sum1 = 0, sum2 = 0,x=0;
	x = low;
	len = (hei - low) / n;
	while (x+len


6.17  定义比较两个身份证大小(假设身份证都是18位,第7位到第14位代表出生年月日)的函数:以出生年月日作为标准;以身份证号作为标准。考虑应该使用结构参数,还是结构指针参数。

#include
int cmp(char *s1,char *s2);
int cmp(char *s1, char *s2)
{
	int k = 0,i=0;
	for ( i = 1; i <= 8; i++)
	{
		if (*s1-*s2>0)
		{
			k = 1;
		}
		else if (*s1-*s2<0)
		{
			k = 2;
		}
	}
	return k;
}
void main()
{
	printf("定义比较两个身份证大小(假设身份证都是18位,第7位到第14位代表出生年月日)的函数:以出生年月日作为标准\n\n");
	int c = 0;
	char *s1, *s2;
	char c1[19] = { '\0' }, c2[19] = {"\0"};
	printf("请输入第一张身份证号码:");
	gets(c1);
	printf("请输入第二张身份证号码:");
	gets(c2);
	s1 = &c1[6];
	s2 = &c2[6];
	c = cmp(s1, s2);
	switch (c)
	{
	case 0:printf("两张身份证号码的出生年月日一样大.");
		break;
	case 1:printf("第一张身份证号码的出生年月日小.");
		break;
	case 2:printf("第二张身份证号码的出生年月日小.");
	default:
		break;
	}
	getch();
}


6.18   编写学生成绩处理程序,提供按照成绩排序输出。(与原题有些不同,原题不详细,且该题和4.7题相似,故做了一些更改)

#include
#include
void student(int n);
void student(int n)
{
	struct date
	{
		int year;
		int month;
		int day;
	};
	struct stu
	{
		char name[21];
		int sex;
		struct date birthday;
		float height;
		int cyuyan;
		int weijifen;
	};
	struct stu *pt;
	pt = (struct stu*)malloc(sizeof(struct stu)*(n + 1));
	int i = 0;
	int weisum = 0, weihei, weilow;
	int csum = 0, chei, clow;
	float weiave = 0, cave = 0;
	for (i = 1; i <= n; i++)
	{
		printf("\n请输入第%d个学生的信息", i);
		printf("\n姓名:");
		scanf("%s", &pt[i].name);
		printf("\n性别(0男 1女):");
		scanf("%d", &pt[i].sex);
		printf("\n出生年龄\n");
		printf("年份:");
		scanf("%d", &pt[i].birthday.year);
		printf("月份:");
		scanf("%d", &pt[i].birthday.month);
		printf("日期:");
		scanf("%d", &pt[i].birthday.day);
		printf("身高(cm):");
		scanf("%f", &pt[i].height);
		printf("C语言成绩:");
		scanf("%d", &pt[i].cyuyan);
		printf("微积分成绩:");
		scanf("%d", &pt[i].weijifen);
	}
	weihei = pt[1].weijifen;
	weilow = pt[1].weijifen;
	chei = pt[1].cyuyan;
	clow = pt[1].cyuyan;
	for (i = 1; i <= n; i++)
	{
		if (cheipt[i].cyuyan)
		{
			clow = pt[i].cyuyan;
		}
		csum = csum + pt[i].cyuyan;
		if (weiheipt[i].weijifen)
		{
			weilow = pt[i].weijifen;
		}
		weisum = weisum + pt[i].weijifen;
	}
	cave = (float)csum / n;
	weiave = (float)weisum / n;
	printf("C语言课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", cave, chei, clow);
	printf("获得C语言最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (chei == pt[i].cyuyan)
		{
			printf("%s\n", pt[i].name);
		}
	}
	printf("微积分课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", weiave, weihei, weilow);
	printf("获得微积分最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (weihei == pt[i].weijifen)
		{
			printf("%s\n", pt[i].name);
		}
	}
}

void main()
{
	printf("编写学生成绩处理程序,提供按照成绩排序输出。\n\n");
	int n = 0;
	printf("请输入学生的人数:");
	scanf("%d", &n);
	student(n);
	getch();
}

                                                                                    

                                                                            业精于勤荒于嬉,行成于思毁于随。撸代码的你,好好加油吧!




你可能感兴趣的:(余勤课后习题答案)