C语言谭浩强第三版第八章例题及课后题:函数

目录

eg8.6用弦截法求方程的根

eg8.7递归求年龄

eg8.8用递归方法求n!

eg8.9汉诺塔

eg8.10比较两个数组的元素

eg8.11有一个一维数组score,内放10个学生成绩,求平均成绩

eg8.14求二维数组元素中的最大值 

8.1求最大公约数和最小公倍数(同6.1)

8.2求一元二次方程的根(似eg5.6)

8.3判断素数(似eg6.8)

8.4转置二维数组的行列

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

8.6写一个函数,将两个字符串连接

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

8.8输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格

8.9统计字符串中字母、数字、空格和其他字符的个数

8.10(50)输入一行字符,将此字符串中最长的单词输出

8.11(30)用起泡法对输入的10个字符按由小到大顺序排列

8.12(20)用牛顿迭代法求根

8.13(25)用递归方法求n阶勒让德多项式的值

8.14输入10个学生5门课的成绩,分别求平均数最高分方差等

8.15(100)输入10个职工的姓名和职工号,进行排序查找

8.16(20)输入一个16进制数,输出相应的十进制数

8.17(35)用递归法将一个整数n转换成字符串

8.18(60)给出年月日,计算该日是该年的第n天


eg8.6用弦截法求方程的根

//eg8.6用弦截法求方程的根

#include<stdio.h>
#include<math.h>

float fun(float x);
float xpoint(float x1, float x2);
float root(float x1, float x2);

float root(float x1, float x2){
	float x = xpoint(x1, x2);
	
	while(fabs(fun(x)) >= 1e-6){
		if(fun(x)*fun(x1) > 0){
			x1 = x;
		}else if(fun(x)*fun(x2) > 0){
			x2 = x;
		}
		
		x = xpoint(x1, x2);
	}
	
	return x;
}

float xpoint(float x1, float x2){
	float x;
	
	return  x = (x1*fun(x2)-x2*fun(x1)) / (fun(x2)-fun(x1));
}

float fun(float x){
	float y;
	
	return y = x*x*x-5*x^2+16*x-80;
}


void main(void){
	float x1;
	float x2;
	float x;
	
	printf("Please input x1 and x2 :");
	scanf("%f%f", &x1, &x2);
	printf("What you just input are :%f , %f\n", x1, x2);
	
	while(fun(x1)*fun(x2) >= 0){
		printf("What you input is wrong, please input again :");
		scanf("%f%f", &x1, &x2);
		printf("What you just input are :%f , %f\n", x1, x2);
	}
	
	x = root(x1, x2);
	
	printf("The root of the function is :%f\n", x);
} 

eg8.7递归求年龄

一个递归问题可以分为“回推”好“地推”两个阶段,要经历若干步才能求出最后的值。显而易见,如果要求递归过程不是无限制进行下去,必须具有一个结束递归过程的条件。

总结:递归其实也不难,首先分析题意,写出递归表达式,根据表达式进行程序编写。

//eg8.7递归求年龄

#include<stdio.h>

int age(int n);

int age(int n){
	int c;
	
	if(n==1){
		c = 10;
	}else{
		c = age(n-1)+2;
	}
	return c;
}

void main(void){
	printf("%d\n", age(5));
}

eg8.8用递归方法求n!

#include<stdio.h>

int factorial(int n);

int factorial(int n){
	int y;
	
	if(n == 0 || n == 1){
		y = 1;
	}else{
		y = n*factorial(n-1);
	}
	
	return y;
}

void main(void){
	int n;
	int y;
	
	printf("Please input a positive number:");
	scanf("%d", &n);
	
	y = factorial(n);
	printf("%d!为%d\n", n, y);
	
}

eg8.9汉诺塔

#include<stdio.h>

void hanoi(int n, char a, char b, char c);
void move(char a, char b);

void move(char a, char b){
	printf("%c ---> %c\n", a, b);
}

void hanoi(int n, char a, char b, char c){
	if(n == 1){
		move(a, c);
	}else{
		hanoi(n-1, a,c,b);
		move(a,c);
		hanoi(n-1, b,a,c);
	}
}


void main(void){
	int n;
	
	printf("Please input a positive number:");
	scanf("%d", &n);
	
	hanoi(n, 'A', 'B', 'C');

	
}

eg8.10比较两个数组的元素

/*
有两个数组a和b,各有10个元素,将它们对应地逐个比较。
如果a数组中的元素大于b数组中的相应元素的数目多余b数组中元素大于a数组中相应元素的数目,
则认为a数组大于b数组,并分别统计出两个数组相应元素大于、小于、等于的次数。 
*/
//1 3 5 7 9 8 6 4 2 0
//5 3 8 9 -1 -3 5 6 0 4



#include<stdio.h>


void initial(int a[], int n);

void initial(int a[], int n){
	int i;
	
	for(i = 0; i < n; i++){
		scanf("%d", &a[i]);
	}
}

void main(void){
	int a[10];
	int b[10];
	int i;
	int big = 0;
	int small = 0;
	int equal = 0;
	int sum = 0;
	
	printf("请输入a数组10个元素的值:");
	initial(a,10);
	printf("请输入b数组10个元素的值:");
	initial(b,10);
	
	for(i = 0; i < 10; i++){
		if(a[i] > b[i]){
			big++;
		}else if(a[i] < b[i]){
			small++;
		}else{
			equal++;
		}
	} 
	
	sum = big-small;
	
	if(sum > 0){
		printf("a数组大于b数组\n");
	}else if(sum < 0){
		printf("a数组小于b数组\n");
	}else{
		printf("a数组等于b数组\n");
	} 
	
	printf("大于的次数为%d,小于的次数为%d,等于的次数为%d\n", big, small, equal); 
}

eg8.11有一个一维数组score,内放10个学生成绩,求平均成绩

数组名做函数参数:此时形参应该是数组名或用指针变量

在被调用函数中声明形参数组的大小是不切任何作用的,因为c语言编译对形参数组不做检查,只是将实参数组的首元素的地址传给形参数组。

形参数组可以不指定大小,在定义数组时在数组名后面跟一个空的方括号。有时为了在被调用函数中处理数组元素的需要,可以另设一个形参,传递需要处理的数组元素的个数。

       

//eg8.11有一个一维数组score,内放10个学生成绩,求平均成绩
//100 56 78 98.5 76 87 99 67.5 75 97
#include<stdio.h>

void initial(float a[], int n);
float average(float a[], int n);
void show(float a[], int n);


void show(float a[], int n){
	int i;
	
	printf("这十个同学的成绩为:");
	for(i = 0; i < n; i++){
		printf("%.1f ", a[i]);
	}
	printf("\n");
}

float average(float a[], int n){
	float av = 0;
	int i;
	
	for(i = 0; i < n; i++){
		av += a[i];
		//printf("av=%.1f\n", av);  //debug 
	}
	printf("av=%.1f\n", av);
	return av /= n;
}

void initial(float a[], int n){
	int i;
	
	for(i = 0; i < n; i++){
		scanf("%f", &a[i]); // scanf("%d", &a[i]);
	}
}

void main(void){
	float a[10];
	float av;
	
	printf("请输入10个学生成绩:");
	initial(a,10);
	show(a,10);
	av = average(a, 10);
	printf("平均成绩为:%.1f\n", av);

} 

eg8.14求二维数组元素中的最大值 

多维数组名做函数参数

 

   

//eg8.14求二维数组元素中的最大值 
//1 3 5 7 2 4 6 8 15 17 34 12
#include<stdio.h>

void initial(int a[][4], int n);
void show(int a[][4], int n);
int max(int a[][4], int n);
void swap(int *a, int *b);

void swap(int *a, int *b){
	int tmp;
	
	tmp = *a;
	*a = *b;
	*b = tmp;
}

int max(int a[][4], int n){
	int m = a[0][0];
	int i,j;
	
	for(i = 0; i < n; i++){
		for(j = 0; j < 4; j++){
			if(m < a[i][j]){
				swap(&m, &a[i][j]);
			}
		}
	}
	
	return m;
}

void show(int a[][4], int n){
	int i,j;
	
	printf("二维数组元素的值为:\n"); 
	for(i = 0; i < n; i++){
		for(j = 0; j < 4; j++){
			printf("%2d ", a[i][j]); 
		}
		printf("\n"); 
	}
}

void initial(int a[][4], int n){
	int i,j;
	int m;
	
	printf("请输入3x4个元素:"); 
	for(i = 0; i < n; i++){
		for(j = 0; j < 4; j++){
			scanf("%d", &a[i][j]); 
		}
	}
}

void main(void){
	int a[3][4];
	int m;
	
	initial(a, 3);
	show(a, 3);
	m = max(a,3);
	printf("该二维数组中的最大值为%d\n", m);
}

8.1求最大公约数和最小公倍数(同6.1)

8.2求一元二次方程的根(似eg5.6)

greater than zero  / smaller than zero  /  equal to zero

//8.2求一元二次方程的根

#include<stdio.h>
#include<math.h>

//2 4 1
//1 2 1
//2 4 3
void diataGreaterThanZero(double diata, double a, double b);
void diataEqualToZero(double diata, double a, double b);
void diataSmallerThanZero(double diata, double a, double b);

void diataEqualToZero(double diata, double a, double b){
	double m;
	double n;
	double x1;
	double x2;
	
	m = -b * 1.0 / (2 * a);
	n = sqrt(diata) * 1.0 / (2 * a);
	
	x1 = m + n;
	x2 = m - n;	
	
	printf("该方程有一对相等的实根:%lf, %lf\n", x1, x2);
	
}

void diataSmallerThanZero(double diata, double a, double b){
	double m;
	double n;
	//double x1;
	//double x2;
	
	m = -b * 1.0 / (2 * a);
	//n = sqrt(diata) * 1.0 / (2 * a);
	n = sqrt((-1)*diata) * 1.0 / (2 * a);
				
	//printf("该方程有一对相等的实根:%lf, %lf\n", x1, x2);
	printf("该方程有两个共轭复根: %lf + i%lf, %lf - i%lf\n", m, n, m, n); 
	
}

void diataGreaterThanZero(double diata, double a, double b){
	double m;
	double n;
	double x1;
	double x2;
	
	m = -b * 1.0 / (2 * a);
	n = sqrt(diata) * 1.0 / (2 * a);
	
	x1 = m + n;
	x2 = m - n;	
	
	printf("该方程有一对不相等的实根:%lf, %lf\n", x1, x2);
} 

void main(void){
	double a, b, c;
	double diata;
	
	
	printf("请输入一元二次方程的三个系数:");
	scanf("%lf%lf%lf", &a, &b, &c);
	printf("三个系数为:%f %f %f\n", a, b, c);

	if(fabs(a) <= 1e-6){//if(a == 0){
		printf("该方程不是一元二次方程\n");
	}

	diata = pow(b,2) - 4*a*c;
	
	if(diata < 0){
		diataSmallerThanZero(diata, a, b);
	}else if(diata == 0){
		diataEqualToZero(diata, a, b);
	}else{
		diataGreaterThanZero(diata, a, b);
	}	
}

8.3判断素数(似eg6.8)

//8.3

//eg6.8判断m是否素数
//质数(prime number)又称素数,有无限个。
//质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。

#include<stdio.h>
#include<math.h>

int isPrimeNumber(int m);

int isPrimeNumber(int m){
	int i; 
	int n = 0;

	for(i = 2; i <= sqrt(m); i++){
		if(m%i == 0){
			n++;
			break;
		}
	}
	
	return n;	
}


void main(void){
	int m;
	int n;
	
	printf("请输入一个正整数:");
	scanf("%d", &m);
	printf("输入的值为:%d\n", m);
	
	n = isPrimeNumber(m);
	
	if(n == 1){
		printf("m不是素数\n" );
	}else{
		printf("m是素数\n");
	}

}

8.4转置二维数组的行列

小技巧:之前的那个题要求存到另一个数组中,所以需要另外开辟一个数组 ;现在这个题只要求转置行列,书中给了一个比较好的方法,只开辟一个变量,就像交换两个数一样,这样就可以节省很多存储空间 

 

错误:如果遍历数组的所有元素,则会转置两次,相当于没有转置;所以课本中从i+1遍历,这样只遍历上三角的元素,对角线也不用转置,所以省了很多操作。

void convert(int a[][N]){
    int i,j;
    int tmp;
    
    for(i = 0; i < N; i++){
        for(j = 0; j < N; j++){
            tmp = a[i][j];
            a[i][j] = a[j][i];
            a[j][i] = tmp;
        }
        printf("\n");
    }    

void convert(int a[][N]){
    int i,j;
    int tmp;
    
    for(i = 0; i < N; i++){
        for(j = i+1; j < N; j++){
            tmp = a[i][j];
            a[i][j] = a[j][i];
            a[j][i] = tmp;
        }
        printf("\n");
    }  
}

 

//8.4
//eg7.4将一个二维数组a的行和列的元素互换,存到另一个二维数组b中

/*
之前的那个题要求存到另一个数组中,所以需要另外开辟一个数组 
现在这个题只要求转置行列,书中给了一个比较好的方法,只开辟一个变量,
就像交换两个数一样,这样就可以节省很多存储空间 
*/ 
#include<stdio.h>

#define N  3

void initial(int a[][N]);
void show(int a[][N]);
void convert(int a[][N]);

/* 
void convert(int a[][N]){
	int i,j;
	int tmp;
	
	for(i = 0; i < N; i++){
		for(j = 0; j < N; j++){
			tmp = a[i][j];
			a[i][j] = a[j][i];
			a[j][i] = tmp;
		}
		printf("\n");
	}
	
} 
*/

void convert(int a[][N]){
	int i,j;
	int tmp;
	
	for(i = 0; i < N; i++){
		for(j = i+1; j < N; j++){
			tmp = a[i][j];
			a[i][j] = a[j][i];
			a[j][i] = tmp;
		}
		printf("\n");
	}
	
} 

void show(int a[][N]){
	int i,j;
	
	for(i = 0; i < N; i++){
		for(j = 0; j < N; j++){
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}
	
}

void initial(int a[][N]){
	int i, j;
	
	for(i = 0; i < N; i++){
		for(j = 0; j < N; j++){
			scanf("%d", &a[i][j]);
		}
	}	
}

void main(void){
	int a[N][N];
	
	printf("Please input %dx%d 个元素:", N, N);
	initial(a);

	printf("a数组中的元素为:\n"); 	   //将a数组元素的输出和u具体的元素交换放到一起做了,没有什么影响 
	show(a);
	
	convert(a);
	printf("交换后a数组中的元素为:\n"); 
	show(a);
}


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

小技巧:数组元素反序存放

void convert(char str[]){
    int index;
    int i;
    int tmp;
    
    index = strlen(str);   //找零字符结束标志
    printf("index=%d\n", index);
    
    for(i = 0; i < index/2; i++){   //for(i = 0; i < index; i++){   //和上一个题一样,不能全部遍历,只能遍历一半
        tmp = str[i];
        str[i] = str[index-i-1];     //str[i] = str[index-i+1];
        str[index-i-1] = tmp;     //str[index-i+1] = tmp;
        //printf("**%c**\n", str[i]);
    } 
}

//若index=10,即零字符结束标志在下标为10的地方

 i  ---- index-i-1

0 ----- 9

1 ----- 8

2 ----- 7

3 ----- 6

4 ----- 5

//8.5写一个函数,使输入的字符串按反序存放,在主函数中输入和输出字符串 

#include<stdio.h>
#include<string.h>

void convert(char str[]);
 
void convert(char str[]){
	int index;
	int i;
	int tmp;
	
	index = strlen(str);
	printf("index=%d\n", index);
	
	for(i = 0; i < index/2; i++){   //for(i = 0; i < index; i++){
		tmp = str[i];
		str[i] = str[index-i-1];  //str[i] = str[index-i+1];
		str[index-i-1] = tmp;     //str[index-i+1] = tmp;
		printf("**%c**\n", str[i]);
	} 
}

void main(void){
	char str[100];
	
	printf("请输入一串字符:");
	gets(str); 
	printf("输入的字符串为:%s\n", str);
	
	convert(str);
	printf("按反序存放后的字符串为:%s\n", str);
	
}

8.6写一个函数,将两个字符串连接



#include<stdio.h>
#include<string.h> 

void stringCat(char str1[], char str2[], char str[]);

void stringCat(char str1[], char str2[], char str[]){
	int index; 
	int i;
/*	
	for(i = 0; i < 80; i++){
		if(str1[i] == '\0'){
			index = i;
			break;
		}
	}
*/
	index = strlen(str1);
	printf("index=%d\n", index);
	
	strcpy(str,str1);
	for(i = index; i < strlen(str2)+index+1; i++){
		str[i] = str2[i-index];
	}
	
}

void main(void){
	char str1[80];
	char str2[80];
	char str[80] = {0};
	
	printf("请输入第一串字符:"); 
	gets(str1);

	printf("请输入第二串字符:"); 
	gets(str2);

	stringCat(str1, str2, str);
	printf("合并的字符串为:");
	puts(str);

}

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

//
//abcdefghijklmn
#include<stdio.h>
#include<string.h>

void stringCopy(char str1[], char str2[]); //将1的复制到2 

void stringCopy(char str1[], char str2[]){
	int index;
	int i, j;
	char c;
	
	index = strlen(str1); 
	for(i = 0, j = 0; i < index; i++){
		c = str1[i];
		if(c == 'a' || c == 'o' || c == 'e' || c == 'i' || c == 'u' || c == 'A' || c == 'O' || c == 'E' || c == 'I' || c == 'U'){
			str2[j++] = c;
		}
	}
}

void main(void){
	char str1[80];
	char str2[80];
	
	printf("请输入一串字符:");
	gets(str1); 
	
	stringCopy(str1, str2);
	printf("这串字符中的元音字符有:%s\n", str2);
} 

8.8输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格

小技巧:中间加空间输出

void showBySomeRule(char str[]){
    int i;
    
    for(i = strlen(str); i>0; i--){
        str[2*i] = str[i];
        str[2*i-1] = ' ';
    } 
    printf("%s", str);

思考:为什么要用--的形式?

因为用++的形式会覆盖原值,用--的话先从数组的后面开始,这样就不会影响原来数组中的值;这也给了我们一种新的输出数值的方法。

 

//8.8输入一个4位数字,要求输出这4个数字字符,但没两个数字间空一个空格

/*
//自己输入的这个是数字,但题目要求是字符
//自己的这个没有弄出最终结果,出了一些问题 
#include<stdio.h>

void showBySomeRule(int n);
void showBySomeRule(int n){
	int m = n;
	int tmp;
	int i = 1000;
	
	while(((i*10)%10) == 1){		
		tmp = n/i%10;
		printf("%d ", tmp);
		n %= i;
		//printf("n=%d\n", n);		
		i/=10;
	}
	printf("\n");
}

void main(void){
	int num;
	
	printf("请输入一个4位数字:");
	scanf("%d", &num);
	printf("该4位数字为:%d\n", num);
	
	showBySomeRule(num);
	printf("按规则输出为:");
} 
*/

#include<stdio.h>
#include<string.h>

void showBySomeRule(char str[]);

/* 自己 
void showBySomeRule(char str[]){
	int index;
	int i;
	
	index = strlen(str);
	for(i = 0; i < index; i++){
		printf("%c ", str[i]);
	}
	printf("\n");
}
*/
//课本 
void showBySomeRule(char str[]){
	int i;
	
	for(i = strlen(str); i>0; i--){
		str[2*i] = str[i];
		str[2*i-1] = ' ';
	} 
	printf("%s", str);

} 
 
void main(void){
	char str[80];
	
	printf("请输入4个数字字符:");
	scanf("%s", str);
	printf("该4个数字字符为:%s\n", str);
	
	printf("按规则输出为:");
	showBySomeRule(str);
} 

8.9统计字符串中字母、数字、空格和其他字符的个数

//My address is #123 Shanghai Road,Beijing,100045.
#include<stdio.h>
#include<string.h>

int letter;
int digit;
int space;
int other;

void doIt(char str[]);

void doIt(char str[]){
	char c;	
	int i;
	
	for(i = 0; i < strlen(str); i++){
		c = str[i];
		
		if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')){
			letter++;
		}else if(c == ' '){
			space++;
		}else if(c >= '0' && c <= '9'){
			digit++;
		}else{
			other++;
		}
	}
	
}

void main(void){
	char str[80];
	
	letter = 0;
	space = 0;
	digit = 0;
	other = 0;
	
	printf("请输入一行字符:");
	gets(str);
	
	doIt(str);
	printf("其中英文字母的个数为:%d\n空格数为:%d\n数字数为:%d\n其他字符的个数为:%d\n", letter, space, digit, other);

}

 

8.10(50)输入一行字符,将此字符串中最长的单词输出

由于函数只能向外传递一个值,故自己的做法是传入一个字符数组用来存放最长的单词,而课本是在函数中找到最长单词的起始位置,通过return传出来。

//本题历时50分钟 
#include<stdio.h>
#include<string.h>

//课本是利用函数找到最长单词的起始位置
//She is a beautiful girl.

void longestWord(char str[], char maxword[]);

void longestWord(char str[], char maxword[]){
	int i,j = 0;
	int length = 0;
	int max = 0;
	int flag;
	int preflag = 0;
	char word[80];
	
	
	for(i = 0; i < strlen(str); i++){
		if((str[i] >= 'A') && (str[i] <= 'Z') || (str[i] >= 'a') && (str[i] <= 'z')){
			flag = 1;
		}else{
			flag = 0;
			length = 0;
		}
		
		if((flag ==1 && preflag ==1)|| (flag ==1 && preflag == 0)){
			length++;
		}
				
		preflag = flag;

		if(length == 0){
			j = 0;
		}else{
			word[j++] = str[i];
			word[j] = '\0';
		}
		
		if(max < length){
			max = length;
			strcpy(maxword, word);
		}
		printf("length = %d,max = %d, word = %s\n", length, max, maxword);
	}
		
	
}

void main(void){
	char str[80];
	char word[80];
	int i;
	
	printf("请输入一串字符:");
	gets(str);
	
	longestWord(str, word);
	printf("最长的单词是:%s\n", word);	
} 

8.11(30)用起泡法对输入的10个字符按由小到大顺序排列


#include<stdio.h>
#include<string.h>

void show(char str[], int count){
	int i;
	
	for(i = 0; i < count; i++){
		printf("%c", str[i]);
	}
	printf("\t");
}
void swap(char *a, char *b){
	char tmp;
	
	tmp = *a;
	*a = *b;
	*b = tmp;
}

void bubbleSort(char str[]){
	int i;
	int j;
	
	for(i = 0; i < strlen(str); i++){       
		for(j = 0; j < strlen(str)-i-1; j++){    //for(j = 0; j < strlen(str)-i-; j++){  
		                                        //之前没有-1.导致最后一个字母和'\0'交换,导致后面的输出就缺失了一个字母 
			if(str[j] > str[j+1]){
				swap(&str[j], &str[j+1]);
			}
			show(str, 11);
			printf("strlen(str) = %d \n", strlen(str));
			//printf("%s\n", str);   //为了调试加入 			
		}
	}
}
//
void main(void){
	char str[10];
	
	printf("请输入10个字符:");
	gets(str);
	
	bubbleSort(str);
} 

8.12(20)用牛顿迭代法求根

f = 2x^3 - 4x^2 + 3x -6

f = ((2x -4)x +3)x -6 这样子表示的表达式在运算时可节省时间

 
//8:20-8:40

#include<stdio.h>
#include<math.h>

double root(double a, double b, double c, double d, double x); //求x附近的根 

double root(double a, double b, double c, double d, double x){
	double x0 = 0;
	double x1 = x;
	double y;
	double der;   //derivative  导数
	
	while(fabs(x1-x0) >= 1e-5) {
		x0 = x1;
		
		y = a*pow(x0,3) + b*pow(x0,2) + c*x0 + d;
		der = 3*a*pow(x0,2) + 2*b*x0 + c;
		x1 = x0 - y*1.0/der;
		printf("方程在1.5附近的根为:%f\n", x1);  //for debug
	}
	return x1;
} 
 

void main(void) {
	double a,b,c,d;
	double x;
	double x1;
	
	printf("请输入四个系数的值:");
	scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
	printf("请输入要求哪个值附近的根:");
	scanf("%lf", &x);
		
	x1 = root(a,b,c,d,x);	
	printf("方程在%lf附近的根为:%f\n", x, x1);	
	
}
 

8.13(25)用递归方法求n阶勒让德多项式的值

//14:40-15:05
#include<stdio.h>

double function(int n, double x);

double function(int n, double x){
	double f;
	
	if(n == 0){
		f = 1;
	}else if(n == 1){
		f = x;
	}else{
		f = ((2*n-1)*x - function(n-1, x) - (n-1)*function(n-2,x)) / n;
	}
	
	return f;
}

void main(void){
	double f;
	int n;
	double x;
	
	printf("请输入n和x:"); 
	scanf("%d%lf", &n, &x);
	printf("n=%d, x=%.3lf\n", n, x);
	
	f = function(n,x);
	printf("值为:%.3lf\n", f);
}

8.14输入10个学生5门课的成绩,分别求平均数最高分方差等

要求:输入10个学生5门课的成绩

思考:该如何定义变量,用什么结构?
答案:课本用的是二维数组,10个学生5门课 

/*
思考:该如何定义变量,用什么结构?
答案:课本用的是二维数组,10个学生5门课 
*/
/*
91 79 83 83 91
95 71 81 80 83
86 82 77 91 88
85 76 79 81 82
88 76 84 81 80
87 72 79 91 84
85 77 75 84 93
66 62 64 54 70
89 67 75 86 93
75 73 70 85 82
*/
#include<stdio.h>
//#include<string.h>
#include<math.h>
#define N 10
#define M 5

void initial(double a[][M]);
void averageScoreOfEachStudent(double a[][M], double av[]);
void averageScoreOfEachCourse(double a[][M], double av[]);
double maxScore(double a[][M], int *row, int *col);
void swap(double *a, double *b);
void show(double a[], int count);
double variance(double a[], int count);
double sumScore(double a[],int count);
void square(double a[], int count, double b[]);

void square(double a[], int count, double b[]){
	int i;
	
	for(i = 0; i< count; i++){
		b[i] = a[i]*a[i];
	}
}
double sumScore(double a[],int count){
	int i;
	double sum = 0;
	
	for(i = 0; i < count; i++){
		sum+=a[i];
	}
	return sum;
}
 
double variance(double a[], int count){
	double diata;
	double b[count];
	
	square(a,count, b);
	
	return diata = sumScore(b, count)*1.0 / count - pow((sumScore(a, count)/count) ,2);
}

void show(double a[], int count){
	int i;
	
	for(i = 0; i < count; i++){
		printf("%.2lf ", a[i]);
	}
	printf("\n");
}

void swap(double *a, double *b){
	double tmp;
	
	tmp = *a;
	*a = *b;
	*b = tmp;
}

double maxScore(double a[][M], int *row, int *col){
	double max = a[0][0];
	int i, j;
	
	for(i = 0; i < N; i++){
		for(j = 0; j < M; j++){
			if(a[i][j] > max){
				swap(&a[i][j], &max);
				*row = i;
				*col = j;
			}
		}
	}
	return max;
}

void averageScoreOfEachCourse(double a[][M], double av[]){
	int i;
	int j;
	int sum = 0;
	double b[M][N];
		
	for(i = 0; i < N; i++){
		for(j = 0; j < M; j++){
			b[j][i] = a[i][j];
		}
	}
	
	for(i = 0; i < M; i++){
		for(j = 0; j < N; j++){
			sum+=b[i][j];
		}
		av[i] = sum*1.0/N;
		sum = 0;
		//printf("%.2lf\n", av[i]);
	}	
}

void averageScoreOfEachStudent(double a[][M], double av[]){
	int i;
	int j;
	int sum = 0;
	
	for(i = 0; i < N; i++){
		for(j = 0; j < M; j++){
			sum+=a[i][j];
		}
		av[i] = sum*1.0/M;
		sum = 0;
		//printf("%.2lf\n", av[i]);
	}

}

void initial(double a[][M]){
	int i;
	int j;
	
	for(i = 0; i < N; i++){
		printf("请输入第%d个学生的成绩:", i+1);
		for(j = 0; j < M; j++){
			scanf("%lf", &a[i][j]);
		}
		//printf("\n");
	}
}

void main(void){
	double a[N][M];	
	double av1[N];  //每个学生平均分 
	double av2[M];
	double max;
	int row;
	int col; 
	double diata;
	
	initial(a);
	
	averageScoreOfEachStudent(a, av1);
	printf("每个学生平均分为:");
	show(av1, N);
	
	averageScoreOfEachCourse(a, av2);
	printf("每门课平均分为:");
	show(av2, M);
	
	max = maxScore(a, &row, &col);
	printf("最高分为%.2lf,为第%d个学生的第%d门课程\n", max, row+1, col+1);
	
	diata = variance(av1, N);
	printf("平均分方差为:%.2lf\n", diata);
} 

8.15(100)输入10个职工的姓名和职工号,进行排序查找

/*题目要求 
1.输入10个职工的姓名和职工号
2.按职工号由小到大顺序排序,姓名顺序也随之调整
3.要求输入一个职工号,用折半查找法找出该职工的姓名,从主函数输入要查找的职工号,输出该职工姓名 
*/

要求:10个职工的姓名和职工号

分析:用什么数据结构

课本:用一个二维数组存放姓名 name[N][8] (每一个人可存放4个汉字) 

            用一个一维数组存放职工号

1.(1)

void inputData(char name[][8], int num[]){
    int i;
    
    for(i = 0; i < N; i++){
        printf("请输入第%d个职工的姓名:", i+1);
        gets(name[i]);
        printf("请输入第%d个职工的职工号:", i+1);
        scanf("%d", &num[i]);
    } 
}

 

出错了,这样子写程序的话,就只能输入第一个职工的姓名,其余职工的姓名无法输入。

 

(2)

void inputData(char name[][8], int num[]){
    int i;
    
    for(i = 0; i < N; i++){
        printf("请输入第%d个职工的姓名:", i+1);
        gets(name[i]);    //此处注意格式
        printf("请输入第%d个职工的职工号:", i+1);
        scanf("%d", &num[i]);
        getchar();
    } 
}

这样子可以全部输入。

分析:用scanf输入的时候最后会加一个回车作为结束输入的标志,而下一轮的gets函数直接接受这个回车作为自己的输入,所以导致正常的数据无法输入。

 

gets(s)函数与scanf("%s",s)相似,但不完全相同,使用scanf("%s",s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。但换行符会被丢弃,然后在末尾添加'\0'字符。

2.

void sort(char name[][8], int num[]){ //用起泡法排序 
    int i;
    int j;
    
    for(i = 0; i < N-1; i++){
        for(j = 0; j < N-1-i; j++){
            if(num[j] > num[j+1]){
                swap(&num[j], &num[j+1]);
                swapString(name[j], name[j+1]);   //地址
            }
        }
    } 
}

3.查找时,如何实现多次查找,即查找完一次之后判断是否要继续查找

 //一次查找 

   printf("\n请输入要查找的z职工号:");
    scanf("%d", &nu);
    index = search(name, num, na, nu);
    
    if(index == -1){
        printf("该职工号不存在\n");
    }else{
        printf("该职工号所对应的职工为:%s\n", na);
    }
 

 //多次查找

    int flag = 1;

    char  c;
    ......

 

   while(flag == 1){
        printf("\n请输入要查找的职工号:");
        scanf("%d", &nu);
        index = search(name, num, na, nu);
       ......    
        printf("\n是否要继续查找(Y/N 不区分大小写):");
        getchar();   //上一个scanf输入之后有一个回车,这个getchar是为了接收那个回车 
        c = getchar();
        if((c == 'N') || (c == 'n')){
            flag = 0;
        }        

    }
 

 

/*题目要求 
1.输入10个职工的姓名和职工号
2.按职工号由小到大顺序排序,姓名顺序也随之调整
3.要求输入一个职工号,用折半查找法找出该职工的姓名,
从主函数输入要查找的职工号,输出该职工姓名 
*/

/*历时 
1. 5:45 - 6:30    45m 
2  6:45 - 7:15    30m 
3. 7:35 - 8:00    25m
*/

/*数据输入 
刘大哥
2
王大姐
10
安安
36
孙悟空 
4
猪八戒
12
王源
6
苏苏
100
瑶瑶
1
小吕
9
冬冬
78 
*/

#include<stdio.h>
#include<string.h>

#define N 10

void inputData(char name[][8], int num[]); 
//这个8表示一个人的名字最多有4和汉字,name用来存放名字,num用来存放职工号 
void sort(char name[][8], int num[]);
void swap(int *a, int *b);
void showOneDimension(int a[]);
void showTwoDimension(char a[][8]);
void swapString(char str1[], char str2[]);
int search(char name[][8], int num[], char na[], int nu);

int search(char name[][8], int num[], char na[], int nu){
	int i;
	int index = -1;
	
	for(i = 0; i < N; i++){
		if(num[i] == nu){
			index = i;
			break;
		}
	}
	
	if(index == -1){
		return index;
	}else{
		strcpy(na, name[index]);
	}
} 

void swapString(char str1[], char str2[]){
	char tmp[10];
	
	strcpy(tmp, str1);
	strcpy(str1, str2);
	strcpy(str2, tmp);
} 

void showTwoDimension(char a[][8]){
	int i;
	int j;

	for(i = 0; i < N; i++){
		printf("%-8s", a[i]);
	} 
	
}

void showOneDimension(int a[]){
	int i;
	
	for(i = 0; i < N; i++){
		printf("%-8d", a[i]);
	}
	printf("\n");
}

void swap(int *a, int *b){
	int tmp;
	
	tmp = *a;
	*a = *b;
	*b = tmp;
}

void sort(char name[][8], int num[]){ //用起泡法排序 
	int i;
	int j;
	
	for(i = 0; i < N-1; i++){
		for(j = 0; j < N-1-i; j++){
			if(num[j] > num[j+1]){
				swap(&num[j], &num[j+1]);
				swapString(name[j], name[j+1]);
			}
		}
	} 
}

void inputData(char name[][8], int num[]){
	int i;
	
	for(i = 0; i < N; i++){
		printf("请输入第%d个职工的姓名:", i+1);
		gets(name[i]);
		printf("请输入第%d个职工的职工号:", i+1);
		scanf("%d", &num[i]);
		getchar();
		//flushall();
	} 
}

/*
gets(s)函数与scanf("%s",s)相似,但不完全相同,
使用scanf("%s",s) 函数输入字符串时存在一个问题,
就是如果输入了空格会认为字符串结束,空格后的字
符将作为下一个输入项处理,但gets()函数将接收输
入的整个字符串直到遇到换行为止。
但换行符会被丢弃,然后在末尾添加'\0'字符。
*/


void main(void){
	char name[N][8];
	int num[N];
	int nu;
	char na[8] = {0};
	int index;
	int flag = 1;
	char c;
	
	inputData(name, num);
	printf("\n");	
	
	printf("按职工号排序后的结果为:\n");
	sort(name, num);
	showOneDimension(num);
	showTwoDimension(name);
	printf("\n");
/*	
	printf("\n请输入要查找的职工号:");
	scanf("%d", &nu);
	index = search(name, num, na, nu);
	
	if(index == -1){
		printf("该职工号不存在\n");
	}else{
		printf("该职工号所对应的职工为:%s\n", na);
	}
*/
	while(flag == 1){
		printf("\n请输入要查找的职工号:");
		scanf("%d", &nu);
		index = search(name, num, na, nu);
	
		if(index == -1){
			printf("该职工号不存在\n");
		}else{
			printf("该职工号所对应的职工为:%s\n", na);
		}
		
		printf("\n是否要继续查找(Y/N 不区分大小写):");
		getchar();   //上一个scanf输入之后有一个回车,这个getchar是为了接收那个回车 
		c = getchar();
		if((c == 'N') || (c == 'n')){
			flag = 0;
		}		
	}
	
}

8.16(20)输入一个16进制数,输出相应的十进制数

// 15:20 -j8 
#include<stdio.h>
#include<math.h>

int change(int num16);

int change(int num16){
	int each;
	int num10 = 0;
	int i = 0;
	
	while((each = num16 % 10)){
		num10 += each*pow(16,i++); 
		num16 /= 10;
	}
	
	return num10;
}
	

void main(void){
	int num16;
	int num10;
	
	printf("请输入一个16进制的数:");
	scanf("%d", &num16);
	num10 = change(num16);
	printf("16进制的%d对应的10进制数为:%d\n", num16, num10);
}

8.17(35)用递归法将一个整数n转换成字符串

void main(void){
    putchar(1+'0');
    printf("\n%d\n", 1+'0');
    printf("%c\n", 1+'0');

putchar函数的基本格式为:putchar(c)。

(1)当c为一个被单引号(英文状态下)引起来的字符时,输出该字符(注:该字符也可为转义字符);

(2)当c为一个介于0~127(包括0及127)之间的十进制整型数时,它会被视为对应字符的ASCII代码,输出该ASCII代码对应的字符;

(3)当c为一个事先用char定义好的字符型变量时,输出该变量所指向的字符。

用递归法将一个整数n转换成字符串

void convert(int n){
    int i;
    
    if((i = n/10) != 0){
        convert(i);
    }
    putchar(n%10 + '0');
}

 

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

// 15:50 - 16:25  (照着课本写的)

#include<stdio.h>

void convert(int n);

void convert(int n){
	int i;
	
	if((i = n/10) != 0){
		convert(i);
	}
	putchar(n%10 + '0');
}

void main(void){
	int num;
	
	printf("请输入一个整数:");
	scanf("%d", &num);
	
	if(num < 0){
		putchar('-');
		num = -num;
	}
		
	convert(num);
	putchar('\n');
	
} 

8.18(60)给出年月日,计算该日是该年的第n天

//自己

int dayOfTheYear(int year, int month, int day){
    int num = 0;
    
    switch(month){
        case 1:  num=day; break;
        case 2:     num=31+day; break;
        case 3:     num=31+28+day; break;
        case 4:  num=31+28+31+day; break;
        case 5:  num=31+28+31+30+day; break;
        case 6:  num=31+28+31+30+31+day; break;
        case 7:  num=31+28+31+30+31+30+day; break;
        case 8:  num=31+28+31+30+31+30+31+day; break;
        case 9:  num=31+28+31+30+31+30+31+31+day; break;
        case 10: num=31+28+31+30+31+30+31+31+30+day; break;
        case 11: num=31+28+31+30+31+30+31+31+30+31+day; break; 
        case 12: num=31+28+31+30+31+30+31+31+30+31+30+day; break;            
    }
    if((leapYear(year) == 1) && (month == 2)){
        num++;
    } 
    return num;
}

//课本

int dayOfTheYear(int year, int month, int day){
    int day_tab[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int i;
    int num = day;
    
    for(i = 0; i < month-1; i++){
        num+=day_tab[i];
    }
    
    if((leapYear(year) == 1) && (month == 2)){
        num++;
    } 

    return num;

 

 

// 输入:  17:20 - 18:00 
// 第几天:18:15 - 18:35

#include<stdio.h>

typedef   unsigned char    boolean;
#define  TRUE    1
#define  FALSE   0

boolean leapYear(int year);
boolean inputDetection(int year, int month, int day);
int dayOfTheYear(int year, int month, int day);
/*
//自己 
int dayOfTheYear(int year, int month, int day){
	int num = 0;
	
	switch(month){
		case 1:  num=day; break;
		case 2:	 num=31+day; break;
		case 3:	 num=31+28+day; break;
		case 4:  num=31+28+31+day; break;
		case 5:  num=31+28+31+30+day; break;
		case 6:  num=31+28+31+30+31+day; break;
		case 7:  num=31+28+31+30+31+30+day; break;
		case 8:  num=31+28+31+30+31+30+31+day; break;
		case 9:  num=31+28+31+30+31+30+31+31+day; break;
		case 10: num=31+28+31+30+31+30+31+31+30+day; break;
		case 11: num=31+28+31+30+31+30+31+31+30+31+day; break; 
		case 12: num=31+28+31+30+31+30+31+31+30+31+30+day; break;			
	}
	if((leapYear(year) == 1) && (month == 2)){
		num++;
	} 
	return num;
}
*/

//课本 
int dayOfTheYear(int year, int month, int day){
	int day_tab[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int i;
	int num = day;
	
	for(i = 0; i < month-1; i++){
		num+=day_tab[i];
	}
	
	if((leapYear(year) == 1) && (month == 2)){
		num++;
	} 

	return num;
} 
 

boolean inputDetection(int year, int month, int day){
	int flag;
	
	if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){
		if(day <= 0 || day > 31){
			printf("您的输入有误\n");
			flag = 0;				
		}else{
			flag = 1;
		}
	}else if(month == 4 || month == 6 || month == 9 || month == 11)	{
		if(day <= 0 || day > 30){
			printf("您的输入有误\n");
			flag = 0;				
		}else{
			flag = 1;
		}			
	}else if(month == 2){   //month == 2
		if(leapYear(year) == 1){
			if(day <= 0 || day > 29){
				printf("您的输入有误\n");
				flag = 0;
			}else{
				flag = 1;
			}
		}else{
			if(day <= 0 || day > 28){
				printf("您的输入有误\n");
				flag = 0;
			}else{
				flag = 1;
			}
		} 
	}else{
		printf("您的输入有误\n");
		flag = 0;	
	}
	printf("\n");
	return flag;	
}
boolean leapYear(int year){
	boolean leap = 0;

	if((year%400 == 0) || ((year%4 == 0) && (year%100 != 0))){
		leap = 1;
		printf("%d年是闰年\n", year);		
	}else{
		printf("%d年不是闰年\n", year);
	}
	 
	 return leap;	
}
void main(void){
	int year;
	int month;
	int day;
	int flag = 1;
	int input;
	int num;
	
	while(flag == 1){
		printf("请输入年、月、日:");
		scanf("%d%d%d", &year, &month, &day);
		printf("year=%d, month=%d, day=%d\n", year, month, day);
		
		leapYear(year);
				
		input = inputDetection(year, month, day);
		if(input == 1){
			flag = 0;
		}
	}
	
	num = dayOfTheYear(year, month, day);
	printf("该天是该年的第%d天\n", num);
	
} 

 

 

 

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安安csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值