C语言(谭浩强第5版)课后习题知识总结
目录
第一章
第二章
第三章
第四章
第五章
第六章
第七章
第八章
第九章
第十章
第一章
1.程序:就是一组计算机能够识别和执行的指令集合,每一条指令使计算机执行特定操作。
程序设计:从确定任务到得到结构、写出文档的全过程。
2.为什么需要计算机语言?
计算机语言解决了人和计算机交流的语言问题,使得人和计算机都能够识别。
高级语言有哪些特点?
C语言、Java、C++、python、GO 高级语言的数据类型比汇编语言更加丰富,高级语言更加亲近自然语言,人们更容易掌握高级语言 高级语言的编写代码需要经过编译才能编程可执行程序;
高级语言和具体的计算机结构是没有很强的关系,机器语言和计算机有较强的关系
3.解释名词含义:
源程序(.c):未编译的按照一定的程序设计语言规范书写的文本文件,是一系列人类可读的计算机语言指令
目标程序(.obj):源程序经过编译后可直接被计算机运行的机器码集合,在计算机文件上以.obj作扩展名
可执行程序(.exe):将所有编译后得到的目标模块链接装配起来,在与函数库相连接成为一个整体,生成一个可供计算机执行的目标程序
程序编辑:上机输入或编辑源程序代码
程序编译:
1)用C提供的“预处理器”,对程序中的预处理指令进行编译预处理
2)对源程序进行语法检查,判断是否有语法错误,直到没有语法错误为止
3)自动把源程序转换为二进制形式的目标程序
程序链接:将所有编译后得到的目标模块链接装配起来,在与函数库相连接成为一个整体的过程称为程序链接
程序:一组计算机能识别和执行的指令和代码,运行于计算机上,满足人们的某种需求的信息化工具
程序模块:由汇编程序、编译程序、装入程序或翻译程序作为一个整体来处理的一级独立的、可识别的程序指令
程序文件:程序的文件,其存储是程序,包括源程序和可执行程序
函数:将一段经常需要使用的代码封装起来,在需要使用时可以直接调用,来完成一定功能
主函数:main函数,程序执行的起点
被调用函数:由一个函数调用另一个函数,则称第二个函数为被调用函数
库函数:编译器提供的可在C源程序中调用的函数,分为C语言标准规定的库函数和编译器特定的库函数
程序调试:将编译的程序投入到实际运行前,用手工或编译程序等方法进行测试,修正语法错误和逻辑错误的过程
程序测试:一个完成了全部或部分功能、模块的计算机程序在正式使用前的检测,以确保该程序能按预定的方式正确地运行
4.printf("%s\n","hello world");
5.共4行,打印时可以调用printf函数进行输出并用\n换行
第二章
1.算法:对求解问题地步骤,对特定问题求解步骤地一种描述
2.结构化算法:由一些顺序、选择、循环等基本结构按照顺序组成,在基本结构之间不存在向前或向后地跳转,流程地控制只存在于一个基本地范围之内;
优点:便于编写,可读性高,修改和维护方便简单,可减少程序出错地机会,提高了程序可靠性,保证了程序地质量,因此体长结构化算法
非结构化算法,流程不受限制地随意跳来跳去,使流程图毫无规律,在阅读时难以理解算法地逻辑,难以阅读和修改,其可靠性和可维护性难以保证
3.三种基本结构:
顺序结构:一种线性、有序地结构,依次执行各行各语句模块
选择结构:根据条件成立与否选择程序执行地通路
循环结构:重复执行一个或几个模块,直到满足某一条件为止,只有一个入口,只有一个出口 结构内地每个部分都有机会被执行到 结构内不能出现死循环
4. 辗转相除法: 如果M小于N,交换M和N,M中存储大数,N中存储小数 N不等于0,循环进行下一个操作 r=m%n; m=n; n=r; N等于0,M即为最大公约数
5.略
6.伪代码表示算法
7.结构化程序设计(SP):进行以模块功能和处理过程设计为主地详细设计原则,采用自顶向下、逐步细化的程序设计方法,先把一个复杂的大问题分解为若干个小问题,对每个小问题编写一个功能上的独立的程序快(模块),将各程序块进行组合成完成的程序 自顶向下 逐步细化 模块化设计 结构化编码
8.略
第三章
1.编程题
2.编程题
3.编程题
4.改错题
5.编程题
6.编程题
7.编程题
8.编程题
(以上题目超级简单,详见《C程序设计》(谭浩强)第5版)
第四章
1.算数运算符:
常见的四则运算:
操作:加减乘除、自增、增减、取模(整除取余),优先级:++ / -- / * / % / + / -
关系运算符:在C中关系运算通常被认定为比较运算;
操作:大于、小于、大于等于、小于等于、等于、不等于,优先级:>、<、≥、≤、==、≠
逻辑运算符:在C中逻辑运算实际上是“与或非”,运算符:与(&&)、或(||)、非(!)
优先级:非、与、或 以上所有优先级:自加、自减、非、算数运算符、关系运算符、逻辑运算符
2.真和假的表示:
逻辑常量:0和1,表示两种对立的状态 - 假、真 逻辑变量:任意数字、任意字符、表达式 - 1>2 真和假的判断: 判断:0表示假、非0表示真
3.略
4.求最大
int main()
{int a, b, c;printf("input three number:>");scanf("%d %d %d", &a, &b, &c);int max;if (a > b){max = a;}else {max = b;}if (max < c){max = c;}printf("max is :%d\n", max);
system("pause");return 0;
}
5.判断输入的数据是否小于1000 小于1000->求平方根 不小于1000->重新提示输入 2.得到平方根,打印输出整数部分
#include <math.h>
int main()
{double num;printf("请输入一个正数:>");scanf("%lf", &num);if (num < 0 || num >= 1000){printf("请输入一个0~999之间的正数:>");scanf("%lf", &num);}double x = sqrt(num);printf("%.0lf\n", x);//printf("%.0lf\n", sqrt(num));system("pause");return 0;
}
6.如果x<1 则y=x 如果x>=1&&x<10 则y=2x-1 如果x>=10 则y=3x-11
#include <stdio.h>
int main()
{int x, y;printf("请输入一个数字x = ");scanf("%d", &x);if (x < 1){y = x;}else if (x >= 1 && x < 10){y = 2 * x - 1;}if(x >= 10){y = 3 * x - 11;}printf("y = %d\n", y);system("pause");return 0;
}
7.(1)和(2)都不符合
8.根据成绩所在区间,选择不同的分支语句,得到不同的成绩评级 score >= 90 'A' score >= 80 && score <90 'B' score >= 70 && score <80 'C' score >= 60 && score <70 'D' score <60 'E'
#include <stdio.h>
int main()
{float score;char result;printf("请输入成绩:>");scanf("%d", &score);if (score >= 90){result = 'A';}else if (score >= 80 && score < 90){result = 'B';}else if (score >= 70 && score < 80){result = 'C';}else if (score >= 60 && score < 70){result = 'D';}else{result = 'E';}printf("%c\n", result);system("pause");return 0;
}
8.略
9.求一个整数有多少位 若数据大于99999或数据小于0则不满足要求,提示错误信息并退出 若数据大于等于10000,则是五位数 若数据大于等于1000,且小于10000,则是四位数 若数据大于等于100,且小于1000,则位三位数 若数据大于等于10,且小于100,则是二位数 若数据小于10,则是一位数
#include <stdio.h>
int main()
{int num;printf("请输入一个不大于5位的正整数:>");scanf("%d", &num);if (num<0 || num>99999){printf("输入的数据不符合规则!\n");return -1;}if (num >= 10000){printf("这个数字是5位数!\n");}else if (num >= 1000 && num < 10000){printf("这个数字是4位数!\n");}else if (num >= 100 && num < 1000){printf("这个数字是3位数!\n");}else if (num >= 10 && num < 100){printf("这个数字是2位数!\n");}else{printf("这个数字是1位数!\n");}printf("%d\n", num);system("pause");return 0;
}
2.分别输出每一位数字 num num/10000=第一位数字 num%10000/1000=第二位数字 num%1000/100=第三位数字 num%100/10=第四位数字 num%10=第五位数字
#include <stdio.h>
int main()
{int num;printf("请输入一个不大于5位的正整数:>");scanf("%d", &num);if (num<0 || num>99999){printf("输入的数据不符合规则!\n");return -1;}if (num > 10000){printf("%d ", num / 10000);}if (num > 1000){printf("%d ", num % 10000 / 1000);}if (num > 100){printf("%d ", num % 1000 / 100);}if (num > 10){printf("%d ", num % 100 / 10);}printf("%d \n", num % 10);system("pause");return 0;
}
3.逆序输出每一位数字 将第二个问题思想反过来构思
#include <stdio.h>
int main()
{int num;printf("请输入一个不大于5位的正整数:>");scanf("%d", &num);if (num<0 || num>99999){printf("输入的数据不符合规则!\n");return -1;}printf("%d ", num % 10);if (num > 10){printf("%d ", num % 100 / 10);}if (num > 100){printf("%d ", num % 1000 / 100);}if (num > 1000){printf("%d ", num % 10000 / 1000);}if (num > 10000){printf("%d ", num / 10000);}printf("\n");system("pause");return 0;
}
10.奖金=110% i<=10000 10w - 奖金=满额的10万奖金+超出(1+10000)7.5% i>10000&&i<=20000 10w0.1 20w - 奖金 = 满额的20万奖金 + 超出(1 + 20000)5 % i>20000&&i<=40000 10w0.1+10w0.075 40w - 奖金 = 满额的40万奖金 + 超出(1 + 40000) * 5 % i>40000&&i<=60000 10w0.1+10w0.075+20w*0.05 60w - 奖金 = 满额的60万奖金 + 超出(1 + 60000) * 3 % i>60000&&i<=100000 10w0.1+10w0.075+20w0.05+40w0.03 100w - 奖金 = 满额的100万奖金 + 超出(1 + 100000) * 1 % i>100000
使用switch语句 将利润分为10个档次 10 20 30 40 50 60 70 80 90 100 使用利润除以10w得到利润等级 int level=i/100000
#include <stdio.h>
int main()
{double salary1 = 100000 * 0.1;//10wdouble salary2 = salary1 + 100000 * 0.075;//20wdouble salary3 = salary2 + 200000 * 0.05;//40wdouble salary4 = salary3 + 200000 * 0.03;//60wdouble salary5 = salary4 + 400000 * 0.015;//100double i, salary;int level = i / 100000;printf("请输入你所创造的利润:>");scanf("%lf", &i);switch (level){case 0:salary = i*0.01;break;case 1:salary = salary1 + (i - 100000)*0.075;break;case 2:case 3:salary = salary2 + (i - 200000)*0.05;break;case 4:case 5:salary = salary3 + (i - 200000)*0.03;break;case 6:case 7:case 8:case 9:salary = salary4 + (i - 200000)*0.015;break;default:salary = salary5 + (i + 1000000)*0.01;break;}printf("%0.2f\n", salary);system("pause");return 0;
}
11.四个数字升序输出 1.找出四个数中最大的数字 a与b比较,如果a<b,数据交换,a中存放较大的数据,然后逐次a与c比较,a与d比较 最终a中存放最大的数字 2.在b c d三个数字中找出最大的数字放到b b与c进行交换,然后再d进行比较交换 3.在c d两个数字中找出较大的数字,放到c中 c与d比较交换 最后,a b c d四个数字就从大到小交换了
#include <stdio.h>
int main()
{int a, b, c, d;printf("请输入四个数字:>");scanf("%d %d %d %d", &a, &b, &c, &d);if (a < b){int tmp = a; a = b; b = tmp;}if (a < c){int tmp = a; a = c; c = tmp;}if (a < d){int tmp = a; a = d; d = tmp;}if (b < c){int tmp = b; b = c; c = tmp;}if (b < d){int tmp = b; b = d; d = tmp;}if (c < d){int tmp = c; c = d; c = tmp;}printf("%d %d %d %d\n", a, b, c, d);system("pause");return 0;
}
12.
1.若输入位置在塔的范围之内,则高度为10㎝,范围之外为0㎝
2.若输入的位置相对于圆心的位置,则长度是否大于半径 长度大于半径,则在范围之外 长度小于等于半径,则在范围之内
3.将四个塔化为一个塔的运算 将输入的位置坐标求取绝对值,进行计算 求取绝对值的接口 double fabs(double num) 求取平方根的接口 double sqrt(double num)
1.获取键盘输入的x,y
2.计算坐标值的绝对值 fx,fy
3.计算坐标值距离圆心的长度 输入的坐标值的位置-圆心的坐标位置=相对于圆心的坐标
4.求取两个位置的直线距离的长度 相对于圆心x距离的平方+相对于距离y的平方=1
5.判断直线距离是否大于半径
#include <stdio.h>
#include <math.h>
int main()
{float x, y;printf("请输入坐标值x,y:>");scanf("%f %f", &x, &y);float fx = fabs(x);float fy = fabs(y);float lx = fx - 2;float ly = fx - 2;float len = sqrt((lx*lx + ly*ly));if (len > 1){printf("输入的位置的建筑物高度为0\n");}else{printf("输入的位置的建筑物高度为10㎝\n");}system("pause");return 0;
}
第五章
1.略
2.
#include <stdio.h>
#include <math.h>
int main()
{int sign=1;double pi=0.0,n=1.0,term=1.0;int count=0;while(fabs(term)>=1e-6){pi=pi+term;n=n+2;sign=-sign;term=sign/n;count++;}pi=pi*4;printf("pi=%10.8f\n",pi);printf("count=%d\n",count);return 0;
}#include <stdio.h>
#include <math.h>
int main()
{int sign=1;double pi=0.0,n=1.0,term=1.0;int count=0;while(fabs(term)>=1e-8){pi=pi+term;n=n+2;sign=-sign;term=sign/n;count++;}pi=pi*4;printf("pi=%10.8f\n",pi);printf("count=%d\n",count);return 0;
}
3.输入两个正整数m和n,求其最大公约数和最小公倍数
最大公约数: “辗转相除法”,以除数和余数反复做除法运算,当中余数为0的时候,就取当中的算式当中的除数为最大公约数
最小公倍数: 两个自然数的乘积=最大公约数最小公倍数
1.从标准输入当中获取两个数字
2.区分两个正整数的较大值(较大值%较小值)
3.辗转相除法-->最大公约数
4.两者的乘积/最大公约数=最小公倍数
5.输出
#include <stdio.h>
int main() { int n, m; scanf("%d比较两个值中的较大值和较小值%d", &n, &m); if (n < m) { int tmp = n; n = m; m = tmp; } //为最小公倍数保存两者的乘积,因为在 //辗转相除法的时候,n,m当中的值会发生变化 int total = nm; int r = -1;//r 代表余数 while (m != 0){ r = n%m; //为下一次做准备 n = m; m = r; } //当前最大公约数经过上面计算已经保存在n中了 printf("最大公约数为:> %d\n", n); printf("最小公倍数为:> %d\n", total / n); system("pause"); return 0;
}
4.输入一行字符,分别统计字母、空格、数字和其他字符
1.从标准输入当中获取一行字符,对每一个字符进行甄别,判断是字母、数字、空格还是其他字符 2.getchar函数 可以从标准输入中获取一个字符 输入多个字符后,getchar从缓冲区中读取字符 输入多个字符,用getchar来循环读取 输入一行字符串后,尾部以\n结束 意味着当读到\n时就结束了 3.统计 ['a', 'a']或['A','Z']---》英文字符 ''---->空格字符 ['0','9']---->数字字符 其他字符
#include <stdio.h>
int main()
{ int eng_char = 0;//英文字符 int space_char = 0;//空格字符 int digit_char = 0;//数字字符 int other_char = 0;//其他字符 int c; while ((c = getchar() )!= '\n') { if ((c >= 'a'&&c <= 'z') || (c >= 'A'&&c <= 'Z')) { eng_char++; } else if (c == ' ') { space_char++; } else if (c >= '0'&&c <= '9'){digit_char++; } else { other_char++; } } printf("英文字符:%d个,空格字符:%d个,数字字符:%d个,其他字符:%d个\n", eng_char, space_char, digit_char, other_char); system("pause"); return 0;
}
5.求Sn=a+aa+aaa+aaaa+.........+aaaa.....aa的值。其中a表示一个数字,n表示a的位数,n由键盘输入。
#include <math.h>
#include <string.h>
int main()
{int n = 0;double a, single_num = 0.0,total_sum=0.0;//从标准输入获取数字scanf("%d %lf", &n, &a);for (int i = 0; i < n; i++){single_num += a*pow(10, i);total_sum += single_num;}printf("%lf\n", total_sum);system("pause");return 0;
}
6.求1-20的阶乘
#include <stdio.h>
int main()
{//求1-20的阶乘double total_sum = 0.0;//遍历获取[1,20]当中的每一个数字for (int i = 1; i <= 20; i++){//对每一个数字进行阶乘double single_num = 1.0;for (int j = i; j > 0; j--){single_num *= j;}//对每个数字阶乘的结果进行求和total_sum += single_num;}printf("%lf\n", total_sum);system("pause");return 0;
}
7.求各个表达式的的和
第一个表达式:指的是求1-100的和,1+2+3+……+100,求和之后,和为整数,范围为【1,100】
第二个表达式:指的是求1^2+2^2+3^2+……+50^2,求和之后,和为整数,范围为【1,50】
第三个表达式:指的是求1/1+1/2+1/3+……+1/10,求和之后,和为浮点数,范围为【1,10】
#include <stdio.h>
int main()
{double total_sum = 0.0, sum1 = 0.0, sum2 = 0.0, sum3 = 0.0;//[1-100]for (int i = 1; i <= 100; i++){//累加sum1 += i;//[1-50]if (i <= 50){//累加sum2 += i*i;}if (i <= 10){sum3 = 1.0 / i;}}total_sum = sum1 + sum2 + sum3;printf("%.2lf\n", total_sum);system("pause");return 0;
}
8.当前题意中描述的水仙花数是一个三位数,范围【100,999】 求得三位数当中的每一位数字,可以在代码中可以采用%10的方式
#include <stdio.h>
int main(){int a, b, c;//获取[100,999]的数字for (int i = 100; i <= 999; i++){//获取三位数字中的每一位a = i / 100;b = i / 10 % 10;c = i % 10;//进行判断if (a*a*a + b*b*b + c*c*c == i){printf("%d ", i);}}system("pause");return 0;
}
9.完数:除了自身之外所有因子之和
例如:6=1+2+3 【1,1000】中所有的完数,当然1除外,1的因子本身就是1
1)如何获取【2,1000】之内所有的数字
2)如何获取data这个数字的所有因子之和 什么因子? 如果一个整数a除以整数b(b!=0),余数为0的情况下,我们就称为b是a的因子 如何求data这个数字的所有因子 data % [1,data) data % [1,data/2]==>(data/2,data) 判断 for(int i=1;i<data/2;i++) if(data%[1,data/2]==0) 因子求和
3)判断当前数是否是完数,因子求和的值是否等于该数本身 因子求和==data 如果等于,按照格式输出
int main()
{ for (int data = 2; data <= 1000; data++) { int factor_sum = 0; for (int factor = 1; factor <= data / 2; factor++) { if (data%factor == 0) { factor_sum += factor; } } //判断 if (factor_sum == data) { printf("%d its factors are ", data); for (int factor = 1; factor < data /2; factor++) { if (data%factor == 0) { printf("%d,", factor); } } printf("\n"); } }
system("pause");
return 0;
}
10.对于下一个分式当中的分子 = 上一个分式当中的分子+分母
对于下一个分式当中的分母 = 上一个分式当中的的分子
对于当前的分式,分式的结果并不是一个整数,所以我们应该在代码中使用浮点类型 保存数据的时候使用浮点数
#include <stdio.h>
main()
{//a代表分子,b代表分母,total_sum代表分式之和double a = 2.0, b = 1.0, total_sum = 0.0;for (int i = 0; i < 20; i++){total_sum = a / b;//更新分子和分母double tmp = a;a = a + b;b = tmp;}printf("%lf\n", total_sum);system("pause");return 0;
}
11.注意:保存数据的时候,一定不能使用整数,因为会有小数存在,如果有小数存在,我们在代码中用浮点数进行保存
#include <stdio.h>
int main()
{//定义高度double total_meter = 100.0;//定义小球经过的米数double ball_total_sum = 0.0;for (int i = 0; i < 10; i++){//下落+回弹ball_total_sum += total_meter;//回弹距离等于高度的一半total_meter /= 2;ball_total_sum += total_meter;}//第十次回弹的距离ball_total_sum -= total_meter;printf("小球经过%lf米,第十次回弹的距离为%lf\n", ball_total_sum, total_meter);system("pause");return 0;
}
12.下一天的桃子数量 = 上一天的桃子数量/2-1 (下一天桃子的数量+1)*2=上一天桃子的数量
第10天:1个
第9天: 4个
第8天:10个
第7天:22个
最后,第十天猴子没有吃,只吃了九天
#include <stdio.h>
int main()
{int day = 9;int cur_day_count = 1;int prev_day_count;while (day > 0){prev_day_count = (cur_day_count + 1) * 2;//更新cur_day_count = prev_day_count;day--;}printf("第一天获取桃子的数量%d\n", prev_day_count);system("pause");return 0;
}
13.注意:我们在迭代计算的时候,计算结果有可能会出现小数,需要在代码中使用浮点类型保存数据
fabs函数获取一个数的绝对值
用1e-5表示结果
#include <stdio.h>
int main()
{//从标准输入当中获取a的值float a, x0, x1;scanf("%f", &a);//计算x0和x1的值x0 = a / 2;x1 = (x0 + a / x0) / 2;//判断是否小于10^-5次方while (fabs(x0 - x1) >= 1e-5){//更新x0和x1的值x0 = x1;x1 = (x0 + a / x0) / 2;}printf("[%f]的平方根为[%f]\n", a, x1);system("pause");return 0;
}
14.用牛顿迭代法求方程的根牛顿迭代法https://baike.baidu.com/item/%E7%89%9B%E9%A1%BF%E8%BF%AD%E4%BB%A3%E6%B3%95/10887580导数的规则:
规则1:x^n 导数为n*x^(n-1)
规则2:常数的导数为0 使用Xn+1 - Xn,如果差值的绝对值小于10^-5次方,则我们认为找到了方程在1.5附近的根
用 fabs 函数来计算一个数字的绝对值
用1e-5来表示10^-5次方
#include <stdio.h>
int main()
{//x0代表xn,x1代表xn+1,f代表数,f1代表导数double x0, x1,f,f1;//计算n+1的值x1 = 1.5;do{x0 = x1;f = ((2 * x0 - 4)*x0 + 3)*x0 - 6;f1 = (6 * x0 - 8)*x0 + 3;x1 = x0 - f / f1;} while (fabs(x1-x0)>=1e-5);printf("方程1.5附近的根:%lf\n", x1);system("pause");return 0;
}
15.使用二分法求方程的根
将区间划分为两部分,记录区间的左右断点,并且通过左右断点计算出中间点,每次将中间点带入方程中进行计算
求得结果 结果>0,则我们将中位数赋值给右端点
结果<0,则我们将中位数赋值给左端点 依次类推,直到我们中位数带到方程中计算结果小于10^-5,我们则认为中间点为方程的根 在代码中要进行循环计算,需要判断每次将区间中点带到方程中 fabs函数,可以计算一个数的绝对值 10^-5 ==1e-5
#include <stdio.h>
#include <math.h>
int main()
{double left = -10, right = 10, mid;double tmp = 10;while (fabs(tmp) > 1e-5){mid = (left + right) / 2;tmp = ((2 * mid - 4)*mid + 3)*mid-6;if (tmp > 0){right = mid;}else if (tmp < 0){left = mid;}}printf("方程在(-10,10)之间的根为:%lf\n", mid);system("pause");return 0;
}
16.
上半部分:
4行
第一行:行号为0,空格为3,星星数量为1
第二行:行号为1,空格为2,星星数量为3
第三行:行号为2,空格为1,星星数量为5
第四行:行号为3,空格为0,星星数量为7 关系:空格数=3-行号;星星数=2行号+1
下半部分:
3行
第一行:行号为0,空格数量为1,星星数量为5
第二行:行号为1,空格数量为2,星星数量为3
第三行:行号为2,空格数量为3,星星数量为1 关系:空格数=行号+1;星星数=7-2(行号+1)
#include <stdio.h>
int main()
{//打印上半部分-4行for (int i = 0; i < 4; i++){//打印空格for (int j = 3 - j; j>0; j--){printf(" ");}//打印星星for (int j = 2 * i + 1; j > 0; j--){printf("*");}printf("\n");}//下半部分-3行for (int i = 0; i < 3; i++){//打印空格for (int j = i + 1; j>0; j--){printf(" ");}//打印星星for (int j = 7 - 2 * (i + 1); j > 0; j--){printf("*");}printf("\n");}system("pause");return 0;
}
17.
#include <stdio.h>
int main()
{//列举A的所有对战对象for (int A = 'X'; A <= 'Z'; A++){//列举B的所有对战对象for (int B = 'X'; A <= 'Z'; B++){//列举C的所有对战对象for (int C = 'X'; A <= 'Z'; C++){if (A != 'X'&&C != 'X'&&C != 'Z'&&A != B&&A != C&&B != C){printf("A对战%c,B对战%c,C对战%c\n", A, B, C);}}}}system("pause");return 0;
}
第六章
1.准备数据1-100之内的所有数据,保存在一个数组中 1不是素数,先将1划掉,采用0进行比较 for() 找一个被划掉的数据,数组中不是0的数据 用该数据模上其后序剩余的所有数据 能被整除的,将其剔除掉 不能被整除的,保留
循环结束后,将数组中所有非0的数据就是最终所要找的素数
#include <stdio.h>
#include <stdlib.h>
int main()
{int array[100];//向array数组中填充1~100所有数据for (int i = 0; i < 100; i++){array[i] = i + 1;}//1不是素数,将1划掉-->使用0进行填充array[0] = 0;for (int i = 1; i < 100; ++i){if (0 == array[i]) continue;//现在需要使用array[i]去模其之后所有数据for (int j = i + 1; j < 100; ++j){if (0!=array[j]&&array[j] % array[i]==0){array[j] = 0;}}}//输出所有素数for (int i = 0; i < 100; ++i){if (0 != array[i]){printf("%d ", array[i]);}}printf("\n");system("pause");return 0;
}
2.10个整数进行排序,排序之前,需要先将10个整型数据准备好
可以直接在程序中给死
可以通过输入
保存为整型数据
选择法——升序、降序--->假设为升序
选择法:每一趟,从待排序的数据中找到最大元素所在的位置(找的是给元素的位置而非值),如果该数据不存在区间的末尾,将其与区间最后一个元素进行交换 用for循环来查找
#include <stdio.h>
int main()
{int i, j;int array[10] = { 2, 8, 3, 9, 5, 7, 1, 4, 0, 6 };int maxPos=0,temp;int size_arr = sizeof(array) / sizeof(array[0]);for (i = 0; i < size_arr; ++i){printf("%d ", array[i]);}printf("\n");//设置循环的趟数for (i = 0; i < size_arr; ++i){//具体选择的方式//用选择法来排序maxPos = 0;for (j = 1; j < size_arr-i; ++j){if (array[j]>array[maxPos]){maxPos = j;}}//判断,已经找到元素最大值,就不需要交换了if (maxPos != size_arr - i - 1){//将最大值的空间与当前值的空间交换temp = array[maxPos];array[maxPos] = array[size_arr - i - 1];array[size_arr - i - 1] = temp;}}for (i = 0; i < size_arr; ++i){printf("%d ", array[i]);}printf("\n");system("pause");return 0;
}
3.3*3矩阵对角线之和
采用3行3列的二维数组的方式进行表示
对角线之和:
从左上角到右下角:a0 a1 a2 每个元素行下标与列下标是相等的
从右上角到左下角:a2 a1 a0
#include <stdio.h>
int main()
{int array[3][3];int i, j;int array_left = 0, array_right = 0;//接受矩阵中的数据for (i = 0; i < 3; ++i){for (j = 0; j < 3; ++j){scanf("%d", &array[i][j]);}}//求左上角到右下角对角线元素之和//行下标与列下标是相等的for (i = 0; i < 3; ++i){array_left += array[i][i];}//右上角到左下标对角线元素之和for (i = 0, j = 2; i < 3; i++){array_right += array[i][j];}printf("求左上角到右下角对角线元素之和 %d\n", array_left);printf("右上角到左下标对角线元素之和 %d\n", array_right);system("pause");return 0;
}
4.找到待插入数据在数组中的位置
插入元素
#include <stdio.h>
int main()
{int key = 0;int end = 8;int array[10] = { 0, 1, 2, 3, 4, 6, 7, 8, 9 };printf("请输入要插入的元素:>");scanf("%d", &key);printf("原数组中的元素:0, 1, 2, 3, 4, 6, 7, 8, 9\n");//找待插入元素在数组中的位置--从后往前进行查找//注意:如果待插入元素比较数组中任何一个元素小//因此end应该保证大于等于0,防止越界情况while (key < array[end] && end >= 0){array[end + 1] = array[end];end--;}//插入元素array[end + 1] = key;for (int i = 0; i < 10; ++i){printf("%d ", array[i]);}printf("\n");system("pause");return 0;
}
5.给两个变量分别比较数组中第一个元素与最后一个元素的位置
begin:第一个元素位置
end:最后一个元素位置
将begin与end位置的元素进行交换
begin++ end++ while(begin<end)
#include <stdio.h>
int main()
{int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };printf("逆序之前数组元素序列为:");for (int i = 0; i < sizeof(array)/sizeof(array[0]); ++i){printf("%d ", array[i]);}//从左侧找一个数据,从右侧找一个数据int begin=0, end=sizeof(array)/sizeof(array[0])-1;//定义临时变量进行交换int temp = 0;while (begin < end){temp = array[begin];array[begin] = array[end];array[end] = temp;begin++;end--;}printf("\n");//打印输出printf("逆序之后数组元素序列为:");for (int i = 0; i < sizeof(array)/sizeof(array[0]); ++i){printf("%d ", array[i]);}printf("\n");system("pause");return 0;
}
6.杨辉三角形
用二维数组来存放
第0列中所有的元素都是1
对角线上所有的元素都是1 行下标和列下标都是相等的
其他元素:arrayi=arrayi-1+arrayi-1;
#include <stdio.h>
int main()
{int i, j;//保存杨辉三角形中的数据int array[10][10];for (i = 0; i < 10; ++i){//每一行进行赋值for (j = 0; j <= i; ++j){if (j == 0 || i == j){array[i][j] = 1;}else{//其他位置array[i][j] = array[i - 1][j] + array[i - 1][j - 1];}}}//一行一行的进行打印for (i = 0; i < 10; ++i){for (j = 0; j <= i; ++j){printf("%6d ", array[i][j]);}printf("\n");}system("pause");return 0;
}
7.魔方阵https://baike.baidu.com/item/%E9%AD%94%E6%96%B9%E9%98%B5/10973743古代又称“纵横图”,是指组成元素为自然数1、2、…、n的平方的n×n的方阵,其中每个元素值都不相等,且每行、每列以及主、副对角线上各n个元素之和都相等。
#include <stdio.h>
#include <stdlib.h>
//奇魔方阵
int main()
{int array[100][100] = { 0 };int N;int row = 0, col = 0;int prevRow = 0, prevCol = 0;int i,j;while (1){printf("请输入奇魔方阵的阶数,阶数是3-100之内的奇数:");scanf("%d", &N);if (0 != N % 2 && (N >= 3 && N < 100)){break;}}//放置1:第0行中间的位置col = N / 2;array[row][col] = 1;//对于剩余的N^2-1个元素,按照以下规则来存放for (i = 2; i <= N*N; ++i){//下一个元素存放在当前元素上一行下一列row--;col++;if (row < 0){row = N - 1;}if (col >= N){col = 0;}if (0 != array[row][col]){//row,col该位置已经有元素--前一个元素当前列的下一行row = prevRow + 1;col = prevCol;}array[row][col] = i;prevRow = row;prevCol = col;}//将魔方阵输出for (i = 0; i < N; ++i){for (j = 0; j < N; ++j){printf("%4d", array[i][j]);}printf("\n");}system("pause");return 0;
}
8.二维数组,不考虑数据重复的情况
鞍点https://baike.baidu.com/item/%E9%9E%8D%E7%82%B9/251306#:~:text=%E9%9E%8D%E7%82%B9%EF%BC%88Saddle%20point%EF%BC%89%E5%9C%A8,%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B%20%E4%B8%AD%EF%BC%8C%E6%B2%BF%E7%9D%80%E6%9F%90%E4%B8%80%E6%96%B9%E5%90%91%E6%98%AF%E7%A8%B3%E5%AE%9A%E7%9A%84%EF%BC%8C%E5%8F%A6%E4%B8%80%E6%9D%A1%E6%96%B9%E5%90%91%E6%98%AF%E4%B8%8D%E7%A8%B3%E5%AE%9A%E7%9A%84%E5%A5%87%E7%82%B9%EF%BC%8C%E5%8F%AB%E5%81%9A%E9%9E%8D%E7%82%B9%E3%80%82
如果鞍点存在,该数据一定是唯一的
当然,二维数组中也可能不存在鞍点
找到该行上最大的元素--->max,该元素所在的列号 确认该元素是否为该列上最小的元素
是:鞍点已经找到了,位置鞍点打印 否则返回0,没有鞍点
#include <stdio.h>
#include <stdlib.h>
#define M 3
#define N 4
int main()
{int array[M][N];int i, j;int max, pos=0,flag=0;printf("请输入%d行%d列二维数组:\n",M,N);for (i = 0; i < M; ++i){for (j = 0; j < N; ++j){scanf("%d", &array[i][j]);}}//找鞍点for (i = 0; i < M; ++i){//找该行最大的元素max = array[i][0];for (j = 0; j < N; ++j){if (array[i][j]>max){max = array[i][i];pos = j;}}//确认该元素是否为该列上最大的元素//列号不变,行号增加for (j = 0; j < M; ++j){if (array[j][pos] < max){//不是鞍点,就直接跳出循环break;}}//如果在pos列没有发现比max小的元素,说明max是pos是列上最小的元素if (j == M){//鞍点找到了printf("鞍点为:%d行,%d列%d", i, pos, array[i][pos]);flag = 1;break;}}if (flag != 1){printf("没有鞍点\n");}system("pause");return 0;
}
9.用折半查找法(二分查找法)找出元素在数组中第几个值
区间:【left,right)
区间:【left,right】
key mid = (left + right)/2; 三个结果:相等,小于,大于
if (key == array[mid]) 找到该数据 --->将其下标输出
else if(key > array[mid]) 找不到该数据 ---> 只需要在区间的左半侧来进行查找---->right修改:mid else 到区间的右半侧进行查找---->只需要改变左边界 left修改:mid+1 while(left<right) ---->查找结束
#include <stdio.h>
#include <stdlib.h>
int main()
{int left=0, right=0, mid;int key;int array[] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };//区间采用左闭右开left = 0;right = sizeof(array) / sizeof(array[0]);printf("请输入待查找的数据:>");scanf("%d", &key);while (left < right){//找中间位置//该求中间位置的方式可能为溢出//mid = (left + right) / 2;mid = left + ((right - left) >> 1);//与中间位置数据进行比较//相等-->找到了//大于-->中间位置数据//小于-->中间位置数据if (key == array[mid]){printf("找到该元素,其在数组中的下标为:%d\n", mid);break;}else if (key < array[mid]){left = mid + 1;}else {right = mid;}}if (left == right){printf("抱歉,没有这个数\n");}system("pause");return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{int left = 0, right = 0, mid;int key;int array[] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };//区间采用左闭右闭left = 0;right = sizeof(array) / sizeof(array[0])-1;printf("请输入待查找的数据:>");scanf("%d", &key);while (left <= right){//找中间位置//该求中间位置的方式可能为溢出//mid = (left + right) / 2;mid = left + ((right - left) >> 1);//与中间位置数据进行比较//相等-->找到了//大于-->中间位置数据//小于-->中间位置数据if (key == array[mid]){printf("找到该元素,其在数组中的下标为:%d\n", mid);break;}else if (key < array[mid]){left = mid + 1;}else {right = mid-1;}}if (left > right){printf("抱歉,没有这个数\n");}system("pause");return 0;
}
10.三行文字,每行文本有80个字符 80个字符-->每行可以将其看作是字符串-->字符串是以'\0'开始的
需要获取三行文本
文章应该保存在文件中
通过标准输入方式获取三行文本
大写字母:A-Z --- upper 小写字母:a-z ---low 数字:0-9 ---digit 其他字符: ---other 空格:' '--32 ---space
逐行统计,通过for循环逐个取到每个字符,ch
#include <stdio.h>
#include <stdlib.h>
int main()
{//先输入三行文本//不能使用scanf接收三行文本//scanf 遇到空格、回车就不往后输入了char sz[3][80] = { 0 };int i ,j;int upper = 0, lower = 0, digit = 0, space = 0, other = 0;for (i = 0; i < 3; ++i){gets(sz[i]);}//统计for (i = 0; i < 3; ++i){//只需要在该行中统计到\0的位置for (j = 0; sz[i][j] != '\0'; ++j){//A-Zif (sz[i][j] >= 'A'&&sz[i][j] <= 'Z'){upper++;}//a-zelse if (sz[i][j] >= 'a'&&sz[i][j] <= 'z'){lower++;}//0-9else if (sz[i][j] >= '0'&&sz[i][j] <= '9'){digit++;}//' 'else if (sz[i][j] == ' '){space++;}//其他字符else {other++;}}}printf("大写字母有:%d\n", upper);printf("小写字母有:%d\n", lower);printf("数字字符有:%d\n", digit);printf("空格字符有:%d\n", space);printf("其他字符有:%d\n", other);system("pause");return 0;
}
11.错位打印星号
#include <stdio.h>
#include <stdlib.h>
int main()
{int i ,j;for (i = 0; i < 5; ++i){//前面的空格for (j = 0; j < 2 * i; ++j){printf(" ");printf("* * * * *");}//后面的星号printf("\n");}system("pause");return 0;
}
12.编码与解码采用相同公式处理的
将正数的第i个字母编码为倒数的第i个字母
如何直到ch为正数第多少个字母?
ch-'A' 'B':'B'-'A' ----->实际为ASCII码值相减
#include <stdio.h>
#include <stdlib.h>
int main()
{//获取暗文//假设暗文长度为100个字符char sz[100];gets(sz);//解码--'A'+(26-(ch-'A')-1)//只对字母进行解码for (int i = 0; sz[i]!='\0'; ++i){//'A'-'Z'if (sz[i] >= 'A'&&sz[i] <= 'Z'){sz[i] = 'A' + (26 - (sz[i] - 'A') - 1);}if (sz[i] >= 'z'&&sz[i] <= 'z'){sz[i] = 'a' + (26 - (sz[i] - 'a') - 1);}}printf("解码为:%s\n", sz);system("pause");return 0;
}
13.拼接原理:将s2中的每个字符逐个拷贝到s1的末尾
注意:s1中必须要有足够的空间来容纳s2中的元素 strlen --->求字符串中的有效字符的长度,不包含'\0'
#include <stdio.h>
#include <stdlib.h>
int main()
{char dst[100] = { 0 };char src[50] = { 0 };int i = 0,j=0;printf("请输入目标字符串:>");gets(dst);printf("请输入源字符串:>");gets(src);//找到s1的末尾while (dst[i]!='\0'){i++;}//将src中的每个字符逐个拷贝到dst中while (src[j] != '\0'){dst[i] = src[j];i++;j++;}//注意:需要拷贝'\0'dst[i] = '\0';printf("%s\n", dst);system("pause");return 0;
}
14.字符串比较不能使用字符串长度
字符串比较规则:将字符串中逐个字符相减
strings=0 -->继续往后进行比较
strings<0 -->终止
s1<s2
strings>0 -->终止
s1>s2
#include <stdio.h>
#include <stdlib.h>
int main()
{char s1[100] = { 0 };char s2[100] = { 0 };int ret = 0, i = 0;printf("请输入s1:>");gets(s1);printf("请输入s2:>");gets(s2);//字符串比较规则:只需要将两个字符串逐个进行比较,减法//while ((ret = (s1[i] - s2[i]) != 0) && s1[i] && s2[i])do{ret = s1[i] - s2[i];if (0 != ret){break;}i++;} while (s1[0] != '\0'&&s2[0] != '\0');printf("%d\n", ret);system("pause");return 0;
}
15.原理:将s2中的字符串逐个的拷贝到s1中 保证s1中的字符可以容纳s2中的字符,否则代码会崩溃
#include <stdio.h>
#include <stdlib.h>
int main()
{char s1[100] = { 0 };char s2[100] = { 0 };int i = 0;printf("请输入要拷贝的字符串:>");gets(s2);//拷贝方式:将s2中的每个字符逐个拷贝到s1//while (s1[i] = s2[i++])//先将s2中的元素拷贝到s1[i]//s1[i]中的字符作为判断条件//i++考虑到后面的字符while (s2[i] != '\0'){s1[i] = s2[i];i++;}//把\0赋给s1s1[i] = '\0';printf("拷贝后的字符串s1为:%s\n", s1);system("pause");return 0;
}
第七章
1.最大公约数 穷举法 相减法 欧几里得辗转相除法 欧几里得辗转相除法-递归法 最小公倍数:穷举法,公式法
穷举法--效率不高
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b)
{ int gcd_res; if (a == 0) return b; else if (b == 0) return a; else if (a == b) return a; int gcd_res = a > b ? b : a; while (gcd_res > 1) { if ((a%gcd_res == 0) && (b%gcd_res == 0)) { return gcd_res; } gcd_res--; } return gcd_res;
}
int main()
{ int a, b; printf("请输入a和b:>"); scanf("%d,%d", &a, &b); //最大公约数 int gcd_res = gcd(a, b); printf("%d,%d\n", a, b,gcd_res); system("pause"); return 0;
}
相减法
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b)
{ int gcd_res; if (a == 0) return b; else if (b == 0)return a; else if (a == b) return a; int gcd_res = a > b ? b : a; while (a!=b) { gcd_res = a > b ? (a -= b) : (b -= a); } return gcd_res;
}
int main()
{ int a, b; printf("请输入a和b:>"); scanf("%d,%d", &a, &b); //最大公约数 int gcd_res = gcd(a, b); printf("%d,%d\n", a, b, gcd_res); system("pause"); return 0;
}
欧几里得辗转相除法
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b)
{ int gcd_res; if (a == 0) return b; else if (b == 0) return a; else if (a == b) return a; int mod = a%b; //模数不为0 while (mod) { a = b; b = mod; mod = a%b; } return b;
}
int main()
{ int a, b; printf("请输入a和b:>"); scanf("%d,%d", &a, &b); //最大公约数 int gcd_res = gcd(a, b); printf("%d,%d\n", a, b, gcd_res); system("pause"); return 0;
}
辗转相除法--递归法
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b)
{if (b == 0){return a;}else {return gcd(b, a%b);}
}
int main()
{int a, b;printf("请输入a和b:>");scanf("%d,%d", &a, &b);//最大公约数int gcd_res = gcd(a, b);printf("%d,%d\n", a, b, gcd_res);system("pause");return 0;
}
最小公倍数--穷举法
#include <stdio.h>
#include <stdlib.h>
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("请输入a和b:>");scanf("%d,%d", &a, &b);//最大公约数int gcd_res = gcd(a, b);printf("%d,%d\n", a, b, gcd_res);//最小公倍数int lcm_res = lcm(a, b);printf("%d 和 %d的最小公倍数:>%d\n", a, b, lcm_res);system("pause");return 0;
}
公式法:
#include <stdio.h>
#include <stdlib.h>
//公式法:lcm=a*b/gcd(a,b)
int lcm(int a, int b)
{if (a*b == 0){return 0;}return a*b / gcd(a, b);
}
int main()
{int a, b;printf("请输入a和b:>");scanf("%d,%d", &a, &b);//最大公约数int gcd_res = gcd(a, b);printf("%d 和 %d的最大公约数:>%d\n", a, b, gcd_res);//最小公倍数int lcm_res = lcm(a, b);printf("%d 和 %d的最小公倍数:>%d\n", a, b, lcm_res);system("pause");return 0;
}
2.求一元二次方程的三个根
#include <stdio.h>
#include <stdlib.h>
float disc;
float x1, x2;
float p, q;
void greater_than_zero(int a, int b)
{x1 = (-b + sqrt(disc)) / 2*a;x2 = (-b - sqrt(disc)) / 2*a;
}
void equal_than_zero(int a, int b)
{x1 = x2 = -b / 2 * a;
}
void less_than_zero(int a, int b)
{p = -b / 2 * a;q = sqrt(-disc) / 2 * a;
}
int main()
{int a, b, c;printf("请输入 a b c:>");scanf("%d %d %d", &a, &b, &c);disc = b*b - 4 * a*c;//判别式计算if (disc > 0){greater_than_zero(a, b);printf("disc>0的两个根为:>x1=%f,x2=%f\n", x1, x2);}else if (disc == 0){equal_than_zero(a, b);printf("disc==0的两个根为:>x1=%f,x2=%f\n", x1, x2);}else{less_than_zero(a, b);printf("disc<0的两个根为:>x1=%f,x2=%f\n", p+q, p-q);}system("pause");return 0;
}
3.求素数--基本的方法
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
bool IsPrime(int value)
{for (int i = 2; i < value/2; ++i){if (value%i == 0) return false;}return true;
}
int main()
{int value;bool flag;printf("请输入 value:>");scanf("%d", &value);flag = IsPrime(value);if (flag){printf("%d是素数\n",value);}else{printf("%d不是素数\n",value);}system("pause");return 0;
}
利用开方的方法
#include <stdio.h>
#include <stdlib.h>
bool IsPrime(int value)
{for (int i = 2; i < sqrt(value); ++i){if (value%i == 0) return false;}return true;
}
int main()
{int value;bool flag;printf("请输入 value:>");scanf("%d", &value);flag = IsPrime(value);if (flag){printf("%d是素数\n", value);}else{printf("%d不是素数\n", value);}system("pause");return 0;
}
3.二维数组的转置--行列互换
#include <stdio.h>
#include <stdlib.h>
void PrintArray(int arr[3][3])
{for (int i = 0; i < 3; ++i){for (int j = 0; j < 3; ++j){printf("%d ", arr[i][j]);}printf("\n");}
}
void ReverseArray(int arr[3][3])
{for (int i = 0; i < 3; ++i){for (int j = 0; j < i; ++j){//转置--交换数据int tmp = arr[i][j];arr[i][j] = arr[j][i];arr[j][i] = tmp;}}
}
int main()
{int arr[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };PrintArray(arr);ReverseArray(arr);PrintArray(arr);system("pause");return 0;
}
4.字符串反序存放
#include <stdio.h>
#include <stdlib.h>
void ReverseString(char str[])
{int start = 0;int end = strlen(str) - 1;while (start < end){char tmp = str[start];str[start] = str[end];str[end] = tmp;start++;end--;}
}
int main()
{char str[100] = { 0 };printf("请输入一个字符串:>");gets(str);printf("原始字符串为:>%s\n", str);ReverseString(str);printf("原始字符串为:>%s\n", str);system("pause");return 0;
}
5.将两个字符串进行连接
#include <stdio.h>
#include <stdlib.h>
void LineString(char dest[],char str1[],char str2[])
{int i = 0;while (str1[i] != '\0'){dest[i] = str1[i++];i++;}int j = 0;while (str2[j] != '\0'){dest[i++] = str2[j++];}//被忘了把\0拷贝进去哦dest[i] = '\0';
}
int main()
{char str1[100] = { 0 };char str2[100] = { 0 };char str[200] = { 0 };printf("请输入第一个字符串:>");gets(str1);printf("请输入第二个字符串:>");gets(str2);LineString(str,str1,str2);printf("新的字符串为:>%s\n", str);system("pause");return 0;
}
6.将一个字符串中的元音字母复制到另一个字符串
#include <stdio.h>
#include <stdlib.h>
void CopyString(char str1[],char str2[])
{int i = 0, j = 0;while (str1[i] != '\0'){if (str1[i] == 'a' || str1[i] == 'A' || str1[i] == 'o' || str1[i] == 'O' || str1[i] == 'e' || str1[i] == 'E' || str1[i] == 'i' || str1[i] == 'I' || str1[i] == 'u' || str1[i] == 'U'){str2[j++] = str1[i];}i++;}str2[j] = '\0';
}
int main()
{char str1[100] = { 0 };char str2[100] = { 0 };printf("请输入一串字符:>");gets(str1);printf("原始字符串:> %s\n", str1);CopyString(str2,str1);printf("有元音字符串:> %s\n", str2);system("pause");return 0;
}
7.输入一个无空格的数字,把这个数字以空格输出
#include <stdio.h>
#include <stdlib.h>
void OutString(char digits[])
{int i = 0;while (digits[i]!='\0'){printf("%c", digits[i]);if (digits[i + 1] == '\0'){break;}printf(" ");i++;}
}
int main()
{char digits[5] = { 0 };printf("请输入一个4位数字字符串:>");gets(digits);//2022->2 0 2 2OutString(digits);system("pause");return 0;
}
8.统计字符串中的字母、数字、空格、其他字符的个数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//解法一
int letter, digit, space, other;
void CountString(char str[])
{int i = 0;while (str[i] != '\0'){//统计字母if (str[i] >= 'a'&&str[i] <= 'z' || str[i] >= 'A'&&str[i] <= 'Z'){letter++;}//统计数字else if (str[i] >= '0'&&str[i] <= '9'){digit++;}//空格字符else if (str[i] == ' '){space++;}//统计其他字符else{other++;}i++;}
}
int main()
{char str[256] = { 0 };printf("请输入一个字符串:>");gets(str);printf("原始字符串为:> %s\n", str);CountString(str);printf("字母个数为%d,数字个数:%d,空格个数:%d,其他个数:%d\n", letter, digit, space, other);system("pause");return 0;
}//解法二
int letter, digit, space, other;
void CountString(char str[])
{int i = 0;while (str[i] != '\0'){//统计字母if (str[i] >= 'a'&&str[i] <= 'z' || str[i] >= 'A'&&str[i] <= 'Z'){letter++;}//统计数字else if (str[i] >= '0'&&str[i] <= '9'){digit++;}//空格字符else if (str[i] == ' '){space++;}//统计其他字符else{other++;}i++;}}
int main()
{char str[256] = "GoodBye 2021,Hello 2022 Hello World Change World GoodGoodStudy";printf("原始字符串为:> %s\n", str);CountString(str);printf("字母个数为%d,数字个数:%d,空格个数:%d,其他个数:%d\n", letter, digit, space, other);system("pause");return 0;
}
9.将一个字符串中最长的单词输出
#include <stdio.h>
#include <stdlib.h>
void FindLongWord(char str[],char word[])
{int i, j;i = j = 0;int len = 0;//同时判断字符串是否结束while (str[i] != '\0'&&str[j]!=' '){j = i;while (str[j] != ' '){j++;}len = j - i;if (len > strlen(word)){//拷贝临时最长的单词strncpy(word, str + i, len);}j++;i = j;}
}
int main()
{char line[256] = "A fang abandoned site Han Desert Hill. The fox rabbits swim in groups again. Luxury becomes a spring dream, leaving behind ancient and modern sorrows.";char word[256] = { 0 };FindLongWord(line, word);printf("最长的单词为:> %s\n", word);system("pause");return 0;
}
10.用起泡法(冒泡排序)对字符由小到大排序
#include <stdio.h>
#include <stdlib.h>
void BubbleSort(char str[])
{int n = strlen(str);//控制排序的趟数for (int i = 0; i < n - 1; ++i){//趟数越多,比较的次数越少for (int j = 0; j < n - 1 - i; ++j){if (str[j]>str[j + 1]){//交换字符char tmp = str[j];str[j] = str[j + 1];str[j + 1] = tmp;}}}
}
int main()
{char str[11] = { 0 };printf("请输入10个字符:>");for (int i = 0; i < 10; ++i){scanf("%c", &str[i]);}printf("原始字符序列为:> %s\n", str);BubbleSort(str);printf("排序后字符序列为:> %s\n", str);system("pause");return 0;
}
11.用牛顿迭代法求方程的根
#include <stdio.h>
#include <stdlib.h>
double Root(int a, int b, int c, int d, int x)
{double x0;double f, f1;do{x0 = x;f = a*pow(x0, 3) + b*pow(x0, 2) + c*x0 + d;f1 = 3 * a*pow(x0, 2) + 2 * b*x0 + c;x = x0 - f / f1;} while (fabs(x-x0)>=1e-3);return x;
}
int main()
{int a, b, c, d;double x;printf("请输入系数 a b c d x:>");scanf("%d %d %d %d %lf", &a, &b, &c, &d, &x);double res = Root(a, b, c, d, x);printf("root = %lf\n", res);system("pause");return 0;
}
12.用递归方法求N阶勒让德多项式的值
#include <stdio.h>
#include <stdlib.h>
float Poly(int n, int x)
{if (n == 0){return 1;}else if(n==1){return x;}else{return ((2 * n - 1)*x - Poly(n - 1, x) - (n - 1)*Poly(n - 2, x)) / n;}
}
int main()
{int n, x;printf("请输入n和x的值:>");scanf("%d %d", &n, &x);float result = Poly(n, x);printf("%d阶勒让德多项式的值为:> %f\n", n, result);system("pause");return 0;
}
13.计算10个学生的成绩
#include <stdio.h>
#include <stdlib.h>
#define M 10
#define N 5
//每一位学生的平均分
float avg_stu[M];
//每一门课程的平均分
float avg_course[N];
//最高分
float highest;
//用于记录最高分学生和课程下标
int stu_index, course_index;
//计算方差
float variance;
void avg_score_stu(float score[M][N])
{float sum = 0.0;for (int i = 0; i < M; ++i){sum = 0.0;for (int j = 0; j < N; ++j){sum += score[i][j];}avg_stu[i] = sum / N;}
}
//计算每门课程的平均分
void avg_score_course(float score[M][N])
{float sum = 0.0;for (int i = 0; i < N; ++i){sum = 0.0;for (int j = 0; j < M; ++j){sum += score[j][i];}avg_course[i] = sum / M;}
}
float highest_score(float score[M][N])
{float highest = 0.0;for (int i = 0; i < M; ++i){for (int j = 0; j < N; ++j){if (score[i][j]>highest){highest = score[i][j];stu_index = i;course_index = j;}}}return highest;
}
//平均分的方差
float variance_avg_score()
{float sum_avg_square=0.0;//平均平方和float sum_avg_score=0.0;//平均分的和for (int i = 0; i < M; ++i){sum_avg_square += (avg_stu[i] * avg_stu[i]);sum_avg_score += avg_stu[i];}return (sum_avg_square / M - (sum_avg_score / M)*(sum_avg_score / M));
}
//打印结果的函数
void print_result(float score[M][N])
{printf("NO. cour1 cour2 cour3 cour4 cour5");for (int i = 0; i < M; ++i){printf("NO.-8%d", i + 1);for (int j = 0; j < N; ++j){printf("%-8.1f ", score[i][j]);}printf("%-9.1f\n",avg_stu[i]);}//显示每一门课程的平均分printf("%-5s", "avger:>");for (int i = 0; i < N; ++i){printf("%-9.1f", avg_course[i]);}printf("\n");printf("最高分为:%.1f分,是第%d个同学的第%d门课程\n", highest,stu_index,course_index);printf("平均分的方差为:>%.1f\n", );
}
int main()
{float score[M][N]={{ 1, 2, 3, 4, 5 },{ 2, 4, 5, 6, 7 },{ 3, 4, 5, 6, 7 },{ 4, 5, 6, 7, 8 },{ 5, 6, 7, 8, 9 },{ 6, 7, 8, 9, 10 }, {7,8,9,10,11},{8,9,10,11,12},{9,10,11,12,13},{10,11,12,13,14}};avg_score_stu(score);avg_score_course(score);highest = highest_score(score);variance = variance_avg_score(score);print_result(score);system("pause");return 0;
}
14.用折半查找法查找员工的姓名
#include <stdio.h>
#includ <stdlib.h>
#define N 3
#define NAME_SIZE 10
void Input(int id[], char name[])
{for (int i = 0; i < N; ++i){printf("输入职工号:>");scanf("%d", &id[i]);getchar();//用于忽略所输入的回车符号printf("输入职工的姓名:>");gets(name[i]);}
}
void Output(int id[], char name[])
{for (int i = 0; i < N; ++i){printf("[%d] : [%s]\n", id, name);}printf("\n");
}
void Sort(int id[], char name[])
{char tmp_name[NAME_SIZE];for (int i = 0; i < N - 1; ++i){for (int j = 0; j < N - i - 1; ++j){if (id[j]>id[j + 1]){int tmp_id = id[j];strcpy(tmp_name, name[j]);id[j] = id[j + 1];strcpy(name[j], name[j + 1]);id[j + 1] = tmp_id;strcpy(name[j + 1], tmp_name[j]);}}}
}
void Search(int id[], char name[], int no)
{//折半查找法==二分法查找int low = 0;int high = N - 1;int mid;int key;while (low <= high){mid = (low + high) / 2;if (key == id[mid]){break;}if (key < id[mid]){high = mid - 1;}else{low = mid + 1;}if (low >= high){printf("职工号为%d的职工姓名为%s\n", key, name[mid]);}else{printf("要查找的职工号为:%d的职工不存在!");}}
}
int main()
{int id[N];//职工号char name[N][NAME_SIZE];//职工姓名Input(id, name);Output(id, name);int no;while (1){printf("请输入要查找的职工号:>");scanf("%d", &no);Search(id, name, no);}Sort(id, name);printf("\n");system("pause");return 0;
}
15.用递归法将一个正数N 转换成一个字符
#include <stdlib.h>
#include <stdio.h>
//递归:自己调用自己
void Convert(int val)
{if ((val / 10) != 0){Convert(val / 10);}printf("%c", val % 10 + '0');
}
int main()
{int num;printf("请输入一个要转换的字符串:>");scanf("%d", &num);printf("转换之后的字符为:>");Convert(num);printf("\n");system("pause");return 0;
}
16.给出年月日,计算这一天是这一年的第几天
#include <stdio.h>
#include <stdlib.h>
bool IsLeap(int year)
{return (year % 4 == 0 && year & 100 != 0 || (year % 400 == 0));
}
int GetDayByYMD(int year, int month)
{int days[13] = { 29, 31, 28, 30, 31, 30, 31, 31, 30, 31, 30, 31 };if (month == 2 && IsLeap(year)){return days[0];}return days[month];
}
int GetDayByYMD(int year, int month, int day)
{int days = 0;for (int i = 1; i < month; ++i){days += GetDayByYMD(year, i);}days += day;return days;
}
int main()
{int year, month, day;printf("请输入年月日:>");scanf("%d %d %d", &year, &month, &day);int days = GetDayByYMD(year, month, day);printf("%d年%d月%d日是第%d天\n", year, month, day, days);system("pause");return 0;
}
第八章
1.将a与剩下的两个数字逐个比较交换,将最小的数字放到a中 将b与c进行比较交换,将最小的数字放到b中
#include <stdlib.h>
#include <stdio.h>
int mian()
{int a, b, c;int *p_a = &a, *p_b = &b, *p_c = &c;printf("请输入三个整数,以空格间隔:>");scanf("%d %d %d", p_a, p_b, p_c);if (*p_a > *p_b){int tmp = *p_a;*p_a = *p_b;*p_b = tmp;}if (*p_a < *p_c){int tmp = *p_a;*p_a = *p_c;*p_c = tmp;}if (*p_b>*p_c){int tmp = *p_b;*p_b = *p_c;*p_c = tmp;}printf("%d %d %d\n", a, b, c);system("pause");return 0;
}
2.三个字符串由小到大输出(通过指针改变地址空间)
注意字符串比较
逐次进行字符串之间的比较交换,将最小的放到str1中,将第二小的放到str2中 指针之间的数值交换,并不涉及字符串内容的改变,只是让p_s1指向了最小的字符串
#include <stdio.h>
#include <stdlib.h>
int main()
{char s1[32], s2[32], s3[32];char *p_s1 = s1,*p_s2 = s2,*p_s3 = s3;printf("请输入三个字符串:>");scanf("%s %s %s", p_s1, p_s2, p_s3);if (strcmp(p_s1, p_s2) > 0){char *tmp = p_s1;p_s1 = p_s2;p_s2 = tmp;}if (strcmp(p_s1, p_s3) > 0){char *tmp = p_s1;p_s1 = p_s3;p_s3 = tmp;}if (strcmp(p_s2, p_s3) > 0){char *tmp = p_s2;p_s2 = p_s3;p_s3 = tmp;}printf("%s %s %s\n", p_s1, p_s2, p_s3);system("pause");return 0;
}
3.输入十个数将前后两个数的位置进行交换 数组名:数组的首元素地址
如何通过一个指针访问整个整数--指针的偏移 指针的加减运算
#include <stdio.h>
#include <stdlib.h>
void Input(int array[], int len)
{//捕捉获取10个整数printf("请输入10个整数,以空格间隔:>");for (int i = 0; i < len; i++){scanf("%d", array + i);}return;
}
void Handler(int array[], int len)
{//数据中数据的处理,将最小的数字放到数组中的第一个空间,将最大的数字放到最后int max, min;int max_idx, min_idx;for (int i = 0; i < len; i++){if (max < *(array + i)){max = *(array + i);max = *(array + i);max_idx = i;}}int tmp;if (*array == max){tmp = *array;*array = *(array + min_idx);*(array + min_idx) = tmp;max_idx = min_idx;}tmp = *(array + len - 1);*(array + len - 1) = *(array + max_idx);*(array + max_idx) = tmp;
}
void Print(int array[], int len)
{for (int i = 0; i < 10; i++){printf("%d ", *(array+i));}printf("\n");return;
}
int main()
{int array[10];Input(array, 10);Handler(array, 10);Print(array, 10);system("pause");return 0;
}
4.使用指针完成数组的访问 数组名,数组首元素的地址 指针的加减运算
#include <stdio.h>
#include <stdlib.h>
void Move(int array[], int n, int m)
{//将数组末尾的M个数字移动到最前边for (int i = 0; i < m; i++){int tmp = *(array + n - (n - i));for (int j = n - (m - i); j>i; j--){*(array + j) = *(array + j - 1);}array[i] = tmp;//*(array+i)=tmp;}return;
}
int main()
{int array[32];int *p_array = array;int n, m;printf("请输入N个大小:>");scanf("%d", &n);printf("请输入M的大小,确定要移动末尾多少个字符");scanf("%d", &m);for (int i = 0; i < n; i++){scanf("%d", p_array + i);}Move(array, n, m);for (int i = 0; i < n; i++){printf("%d ", array[i]);}system("pause");return 0;
}
5.有一个数组,有N个人数,每一个人都有各自的编号 统计当前存活人数,remain=n 从第一个人开始报数,直到最后一个人,将报3的全部剔除掉 判断,循环进行每次遍历报数,直到存活人数为0 最后判断最后存活人数的编号为多少 如何使用指针访问数组中的每一个元素? 先定义一个数组,使用指针访问数组中的每一个元素, int array[] int *p=array 数组名就是数组的首元素地址 指针的加减运算 p+2 --> 指针向后偏移2个元素 通过指针的加减运算偏移指针指向位置,进而实现遍历数组
#include <stdio.h>
#include <stdlib.h>
int main()
{int n;//捕捉人数printf("请输入总人数:>");scanf("%d", &n);int people[128];for (int i = 0; i < n; i++){//给每一个进行编号people[i] = i + 1;}//报数int remain = n;//存活人数int num_off = 0;while (remain>1){int *p = people;//获取元素的首地址while (p != people + n)//不等于最后一个元素地址{//每次都从第一个开始if (*p!=0){//当前位置还存在人的话,则进行报数num_off++;//如果该人报数为3,则把他剔除掉,赋给0if (num_off == 3){*p = 0;//报数重新开始num_off = 1;//存活人数-1}}p++;}}for (int i = 0; i < n; i++){if (people[i] != 0){printf("存活人的编号为:%d\n", people[i]);break;}}system("pause");return 0;
}
6.计算字符串长度 字符串,可以理解为一个字符数组,但是有一个\0的表示结尾标志
在数组中,从起始字符开始,到达\0结尾处的长度就是字符串的长度 使用指针访问字符串中每一个字符,进行字符数量统计,直到遇到\0字符
使用指针遍历数组元素 char str[10]="hello"; char *ptr=str;
数组名表示数组首元素的空间地址
指针的偏移运算:指针的加减运算 ptr+1
#include <stdio.h>
#include <stdlib.h>
int MyStrLen(char *str)
{int count = 0;char *ptr = str;while (*ptr != '\0'){ptr++;count++;}return count;
}
int main()
{char str[10];char *ptr = str;printf("请输入一个字符串:>");scanf("%s", ptr);printf("len = %d\n", MyStrLen(str));system("pause");return 0;
}
7.复制字符串 举个例子:hellobit 使用字符指针指向字符串中的第M个字符的位置
从指向位置开始,每个字符都赋值到另一个字符数组中,直到\0字符串结尾标志 char str[32]; char ptr=str; 数组名表示数组的首元素的空间地址 ptr+m
指针的加减运算:将指针指向的位置向前或向后偏移M个元素
获取指针指向空间的数据:对指针进行解引用:ptr
#include <stdio.h>
#include <stdlib.h>
int main()
{int buf1[32], buf2[32];printf("请输入一个字符串:>");scanf("%s", buf1);printf("请输入复制的位置:>");int m;scanf("%d", &m);//输入要复制的位置char *ptr1 = buf1+m;//偏移几个char *ptr2 = buf2;while (*ptr1 != '\0'){*ptr1 = *ptr2;ptr1++;ptr2++;}*ptr2 = '\0';printf("%s\n", buf2);system("pause");return 0;
}
8.字符串:字符数组,实际的内容以一个\0结尾 对字符的各个字符进行统计
遍历判断字符中每个字符是什么样的字符 'A'<=ch<='Z' 'a'<=ch<='z' ch==' ' '0'<=ch<='9' 以上都不满足就是其他的
如何遍历字符串(使用指针)
char buf[1024]; char *ptr=buf; ptr指向的是字符串的起始字符的位置
数组名:表示数组的首元素地址
指针的加减运算
ptr+3 指针向后偏移三个所指向的元素
ptr++ 可以不断向后偏移一个字符,直到所指向的元素是一个字符串结尾表示\0
#include <stdio.h>
#include <stdlib.h>
int main()
{char buf[1024];char *ptr = buf;printf("请输入一个字符串:>");gets(buf);//从标准输入键盘中获取一行字符int upper = 0, lower = 0, digit = 0, space = 0, other = 0;while (*ptr != '\0'){if (*ptr >= 'A'&&*ptr <= 'Z'){}else if (*ptr >= 'a'&&*ptr <= 'z'){upper++;}else if (*ptr >= 'A'&&*ptr <= 'Z'){lower++;}else if (*ptr >= '0'&&*ptr <= ''){digit++;}else if (*ptr == ' '){space++;}else {other++;}ptr++;}printf("%d %d %d %d %d\n", upper, lower, digit, space, other);system("pause");return 0;
}
9.打印一个3*3的矩阵转置
矩阵转置:行变列,列变行
int array3; arrayj=arrayi;
指针对二维数组的访问
指针如何访问一维数组的每一个成员(元素) int array[3],int *ptr=array;
数组名是数组首元素的地址
通过指针的加减运算,完成指向偏移
ptr+2表示指向向后偏移两个所指向的元素
二维数组的访问: int array3; array+1 表示指向向后偏移的一个所指向的元素 (array+1)==array[1] :二维数组的第一个元素,也是一个数组 array1==(array+1)[2] ((array+1)+2)
#include <stdio.h>
#include <stdlib.h>
void Change(int array[3][3], int array1[3][3])
{for (int i = 0; i < 3; i++){for (int j = 0; j < 3; j++){*(*(array + i) + j) = *(*(array1 + j) + i);}}return;
}
int main()
{int array[3][3] = { 0 };printf("请输入一个3*3的矩阵:>\n");//一行和一行进行捕捉for (int i = 0; i < 3; i++){scanf("%d %d %d", &array[i][0], &array[i][1], &array[i][2]);}//定义转置后的数组int array1[3][3];printf("\n");Change(array, array1);for (int i = 0; i < 3; i++){printf("%d %d %d\n", array[i][0], array[i][1],array[i][2]);}system("pause");return 0;
}
10.一个55的矩阵,把最大的值放在中心,4个角分别存放4个最小的元素(顺序为从左到右,从上到下依次从小到大存放)
最大函数的查找:遍历一遍数组,找到最大的数值以及对应在数组中的下标
最小元素的查找: 最小:遍历一遍数组,找到最小的以及下标 次小:
遍历一遍数组,找到最小的以及小标(忽略已经找到的最小)
中心点的下标:行列/2
左上角:0
右上角:列数-1
左下角:列数(行数-1)
右下角:列数行数-1
使用指针完成: 指针对一维数组访问:int array[3];int *p=array;数组名是首元素空间的地址(下标)
指针的偏移运算(指针的加减运算):p+1 根据指针所指的元素来决定的,指的是向前或向后偏移N个所指向的元素
#include <stdio.h>
#include <stdlib.h>
#define INT32_MIN 5
void Handler(int *array, int row, int col)
{//找到最大的数字,以及对应下标int max = INT32_MIN, max_idx;for (int i = 0; i < col*col; i++){if (max < *(array + i)){max = *(array + i);max_idx = i;}}//找到四个中最小的数字以及对应下标int min = INT32_MAX, min_idx[4];for (int i = 0; i < 4; i++){min = INT32_MAX;for (int j = 0; j < row*col; j++){int k;for (k = 0; k < i; k++){if (j == min_idx[k]) break;}if (k != i)continue;//被比较过就忽略if (min>*(array + i)){min = *(array + j);min_idx[i] = j;}}}int center_idx = row*col / 2;int left_up_idx = 0;int right_up_idx = col - 2;int left_down_idx = col*(row - 1);int right_down_idx = col*row - 1;int tmp;tmp = *(array + center_idx);*(array + center_idx) = *(array + max_idx);*(array + max_idx) = tmp;tmp = *(array + left_up_idx);*(array + left_up_idx) = *(array + min_idx[0]);*(array + min_idx[0]) = tmp;tmp = *(array + left_down_idx);*(array + left_down_idx) = *(array + min_idx[1]);*(array + min_idx[0]) = tmp;tmp = *(array + right_up_idx);*(array + right_up_idx) = *(array + min_idx[2]);*(array + min_idx[0]) = tmp;tmp = *(array + right_down_idx);*(array + right_down_idx) = *(array + min_idx[3]);*(array + min_idx[0]) = tmp;return;
}
int main()
{int array[5][5];printf("请输入一个5*5的矩阵数据:>\n");for (int i = 0; i < 5; i++){scanf("%d %d %d %d %d", &array[i][0], &array[i][1], &array[i][2], &array[i][3], &array[i][4] );}printf("\]n");Handler((int *)array, 5, 5);for (int i = 0; i < 5; i++){printf("%d %d %d %d %d\n", &array[i][0], &array[i][1], &array[i][2], &array[i][3], &array[i][4]);}system("pause");return 0;
}
11.冒泡排序算法: 先找到最大的或者最小的,先拿第一个数据,与剩下的所有数据逐次比较交换 找到次大的或者次小的
如何进行字符串比较, int strcmp(char *str1,char *str2);
返回值:大于0,等于0,小于0
如何进行拷贝, strcpy(char *str1,char *str2);
将str2的字符串拷贝到str1中
#include <stdio.h>
#include <stdlib.h>
void StrSort(char str_arr[][32], int n)
{for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){if (strcmp(*(str_arr + i), *(str_arr + j)) < 0){char tmp[32];strcpy(tmp, *(str_arr + i));strcpy(*(str_arr + i), *(str_arr + j));strcpy(*(str_arr + j), tmp);}}}return;
}
int main()
{char str_arr[32][32];printf("请输入要输入的字符串的个数:>");int n;scanf("%d", &n);printf("请输入%d个字符串:\n", n);for (int i = 0; i < n; i++){scanf("%s", str_arr[i]);}printf("\n");StrSort(str_arr, n);for (int i = 0; i < n; i++){printf("%s", str_arr[i]);}system("pause");return 0;
}
12.冒泡排序法: 先找到一遍数组找到最大的数据,保存到第一个空间中
从第二个空间开始,遍历数组,找到最大的数据放到第二个空间中
字符指针数组的使用: 二维字符指针数组: char str_array32; char *ptr_str[32]; 仅仅只是指向了指针的指向,而没有改变其地址
#include <stdio.h>
#include <stdlib.h>
void StrSort(char *p_str[], int n)
{for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){if (strcmp(p_str[i], p_str[j]) < 0){//数组写法/*char *tmp = p_str[i];p_str[i] = p_str[j];p_str[j] = tmp;*///指针写法char *tmp = *(p_str + j);*(p_str + i) = *(p_str + j);*(p_str + j) = tmp;}}}return;
}
int main()
{char str_arr[32][32];char *p_str[32];for (int i = 0; i < 32; i++){p_str[i] = str_arr[i];}printf("请输入字符串个数:>");int n;scanf("%d", &n);printf("请输入%d个字符串:\n");for (int i = 0; i < n; i++){scanf("%d", p_str[i]);}printf("\n");StrSort(p_str, n);for (int i = 0; i < n; i++){printf("%s\n", p_str[i]);}system("pause");return 0;
}
13.用矩形法求定积分的通用函数
矩形法:将一个图形划分为多个小块矩形,求取每个小块矩形的面积,进行相加,得到最终结果 定积分的上下限:0,1
等分区间个数:10000
小块矩形的底部边长:dx=(1-0)/10000
小块矩形的高度:具体使用的函数值
小块矩形面积:Sn=func(x)dx; S=S1+S2+.......+Sn
借助回调函数实现通用接口: 回调函数:被当作参数传递的函数
如何函数当作一个参数进行传递,借助函数指针
就是将函数的地址传递到一个函数中 double sin(double x) double cos(double x) double exp(double x)
函数名就可以表示函数的地址 double (p)(double) 函数指针变量p test (trouble (*p)(double) { p(); }
#include <stdio.h>
#include <stdlib.h>
double calc(double(*handler)(double))
{double dx = (1 - 0) / 10000;double sum = 0;//定积分最终结果for (double i = 0; i <= 1; i += dx){sum += handler(i)*dx;}return sum;
}
int main()
{printf("请选择定积分计算函数(1-sin/2-cos/3-exp):>");int n;int res;scanf("%d", &n);switch (n){case 1:res = calc(sin);break;case 2:res = cal(cos);break;case 3:res = cal(exp);break;default:printf("请输入1~3之间的选项的数字!");}printf("%lf\n", res);system("pause");return 0;
}
14.如何使用指针访问数组中的每一个元素 int array[10]; int *ptr=array; array
数组名 在使用中被认为是数组中首元素空间的地址
指针的加减运算 ptr+2 使指针的指向向前或向后偏移2个所指向的元素(地址)
考查:指针使用和偏移
#include <stdio.h>
#include <stdlib.h>
//对整数逆序排列
void Reverse(int array[], int n)
{int *start = array, *end = array + n-1;for (; start < end; start++,end--){int tmp = *start;*start = *end;*end = tmp;}return;
}
int main()
{int n, array[32];printf("请输入数字的个数:>");scanf("%d", &n);printf("请输入%d个数字,以空格隔开:", n);for (int i = 0; i < n; i++){scanf("%d", array + i);}printf("\n");Reverse(array, n);for (int i = 0; i < n; i++){printf("%d", *(array + i));}printf("\n");system("pause");return 0;
}
15.四个学生,五门课程;求平均分,两门以上不及格的学生,输出其学号和全部课程成绩及平均分;找出平均分成绩在90分以上或全部课程成绩在85分以上的学生 4个学生的5门课程成绩,可以组织成一个四行五列的数组 将每一行的第0个元素的值进行相加,然后除以4
int score4; score0,score1......... 如果通过指针访问二维数组的每一个元素
一维数组访问:int array[10];int ptr=array; 数组名在使用中表示数组的首元素空间地址
通过指针的加减运算:ptr+2 int array4; array -->数组名是数组首元素的地址空间
二维数组的数组名是第0个元素的地址,而第0个元素实际上是一个数组
第一个学生:(array+1) ==array[1]
第一个学生第二门成绩:array1==((array+1)+2)
考查:指针访问二维数组中的每一个元素
#include <stdio.h>
#include <stdlib.h>
void Avg(int score[][5], int n)
{double sum = 0;for (int i = 0; i < 4; i++){sum += *(*(score + i) + 0);}printf("第一门课程的平均分:%f\n", sum);return;
}
void Fail(int score[][5], int n)
{for (int i = 0; i < n; i++){int fail_count = 0, sum = 0;for (int j = 0; j < 5; j++){if (*(*(score + i) + j) < 60){fail_count++;}}if (fail_count <= 2) continue;printf("学号 = %d ", i + 1);for (int j = 0; j < 5; j++){sum += *(*(score + i) + j);printf("%d ", *(*(score + i) + j));}printf("平均分:%f\n", sum / 5.0);}return;
}
void Exe(int score[][5], int n)
{//找出平均分在90分以上或所有成绩在85分以上for (int i = 0; i < n; i++){float sum = 0;int count = 0;for (int j = 0; j < 5; j++){if (*(*(score + i) + j)>85){count++;}sum += *(*(score + i) + j);}if (count == 5 || sum / 5 > 90){for (int j = 0; j < 5; j++){printf("%d ", *(*score + i) + j);}printf("\n");}}return;
}
int main()
{printf("请输入四个学生的五门课程成绩:");int score[4][5];for (int i = 0; i < 4; i++){scanf("%d %d %d %d %d", *(score + i) + 0, *(score + i) + 1, *(score + i) + 2, *(score + i) + 3, *(score + i) + 4);}Avg(score, 4);Fail(score, 4);Exe(score, 4);system("pause");return 0;
}
第九章
1.struct:定义结构体关键字
访问结构体中的成员:点(.)和箭头(->)
闰年:可以被4整除,但是不能被100整除;可以被400整除
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct date
{int _year;int _month;int _day;
};
int main()
{//定义一个日期数组int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };struct date d;//输入数据scanf("%d %d %d", &d._year, &d._month, &d._day);int day = 0;//循环累加for (int i = 1; i < d._month; ++i){day += days[i];}//累加当前月的天数day += d._day;//判断是否为闰年if ((d._year % 4 == 0 && d._year % 100 != 0) || (d._year % 400 == 0)){if (d._month>2){++day;}}printf("这是这一年的第%d天\n", day);system("pause");return 0;
}
2.定一个结构体变量: struct 结构体名称 { 成员变量; };
输入:year month day 1~month-1
天数累加
输出:累加的结果
注意:闰年 month:包含2月判断是否为闰年,不是闰年2月有28天
闰年判断: year%4==0&&year%100!=0 year%400==0
月份数组:12个元素或13个元素保存1~12月
#include <stdio.h>
#include <stdlib.h>
struct date
{int _year;int _month;int _day;
};
days(struct date d)
{//日期数组int num[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };int n = sizeof(num) / sizeof(num[0]);//累加日期int ret = 0;for (int i = 1; i < d._month; ++i){ret += num[i];}//累加当前月的天数ret += d._day;//判断是否包含2月if (d._month>2){if ((d._year % 4 == 0 && d._year % 100 != 0) || (d._year % 400 == 0)){++ret;}}return ret;
}
int main()
{struct date d;printf("请输入日期:>\n");scanf("%d %d %d", &d._year, &d._month, &d._day);printf("这是第 %d 天\n", days(d));system("pause");return 0;
}
3.打印学生的成绩数组
给一个学生的结构体: struct student { int num; char name[10]; int score[3]; }; print(struct student[] stuArr) print(struct student* stuArr) { }
#include <stdio.h>
#include <stdlib.h>
#define LEN 10
struct student
{int num;char name[LEN];int score[3];
};
void print(struct student * stuArr,int num)
{for (int i = 0; i < num; ++i){printf("%d %s %d %d %d %d\n", stuArr[i].num, stuArr[i].name, stuArr[i].score[0], stuArr[i].score[1], stuArr[i].score[2]);}
}
int main()
{struct student stuArr[5];printf("请输入5名学生的数据:学号 名字 成绩1 成绩2 成绩3>");for (int i = 0; i < 5; ++i){scanf("%d %s %d %d %d", &stuArr[i].num, &stuArr[i].name, &stuArr[i].score[0], &stuArr[i].score[1], &stuArr[i].score[2]);}//调用函数,输出数据print(stuArr, 5);system("pause");return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define LEN 3
struct student
{int num;char name[LEN];int score[3];
};
void Input(struct student * stuArr,int n)
{//输入学生的数据printf("输入五名学生的数据 学号 姓名 成绩1 成绩2 成绩3:>\n");for (int i = 0; i < 5; ++i){scanf("%d %s %d %d %d", &stuArr[i].num, &stuArr[i].name, &stuArr[i].score[0], &stuArr[i].score[1], &stuArr[i].score[2]);}
}
void Print(struct student * stuArr,int n)
{printf("请输入%d名学生的数据:>\n", n);for (int i = 0; i < n; ++i){printf("%d %s %d %d %d", stuArr[i].num, stuArr[i].name, stuArr[i].score[0], stuArr[i].score[1], stuArr[i].score[2]);}
}
int main()
{struct student stuArr[5];printf("请输入5名学生的数据:学号 名字 成绩1 成绩2 成绩3>");Input(stuArr, 5);Print(stuArr, 5);system("pause");return 0;
}
5.学生结构体 学号 姓名 成绩数组 平均成绩 输入数据 平均值 最大值平均值
#include <stdio.h>
#include <stdlib.h>
#define LEN 20
#define STUCNT 5
//定义学生结构体
struct student
{int num;char name[LEN];int score[STUCNT];float avg;
};
int main()
{//定义学生结构体数组struct student arr[STUCNT];int maxI;float maxAvg = 0.0;//输入数据printf("请输%d个学生的数据:学号 姓名 成绩1 成绩2 成绩3>\n", STUCNT);for (int i = 0; i < STUCNT; ++i){float avg = 0.0;scanf("%d %s", &arr[i].num, &arr[i].name);for (int j = 0; j < 3; ++j){scanf("%d", &arr[i].score[j]);avg += arr[i].score[j];}//学生的平均值avg /= 3;arr[i].avg = avg;//记录最大数据if (avg>maxAvg){maxAvg = avg;maxI = i;}}//打印数据printf("学号 姓名 成绩1 成绩2 成绩3 平均成绩:>");for (int i = 0; i < STUCNT; ++i){printf("%d %s", arr[i].num, arr[i].name);for (int j = 0; j < 3; ++j){printf("%d", arr[i].score[j]);}printf("%f\n", arr[i].avg);}//打印最高平均成绩的学生数据printf("平均成绩最高的学生:>\n");printf("%d %s %d %d %d %f\n", arr[maxI].num, arr[maxI].name, arr[maxI].score[0], arr[maxI].score[1], arr[maxI].score[2],arr[maxI].avg);system("pause");return 0;
}
6.节点 序号 下一个人的位置 next 开始报数,循环(循环条件为12人)
如果已经退出圈子,直接跳过
报数到3:把此人序号设为0
报数大于3时,置成1 遍历链表,找到序号不为0
#include <stdio.h>
#include <stdlib.h>
#define NUM 13
//定义节点
typedef struct people
{int num;struct people* next;
}people;
int main()
{//定义包含13个人的数据people arr[NUM];//遍历环状链表people* head = arr;for (int i = 0; i < NUM; ++i){head->num = i + 1;head->next = &arr[i + 1];head = head->next;}//构成环状结构arr[NUM - 1].next = arr;//开始报数int count = NUM;//从1开始报数int i = 1;head = arr;while (count > 1){//判断是否已经退出if (head->num == 0){//跳过此人head = head->next;continue;}if (i == 3){//当前此人需要退出printf("第%d个人退出\n", head->num);head->num = 0;count--;}//继续报号++i;head = head->next;//判断报号是否大于3if (i > 3){i = 1;}}//找出编号不为0的人while (head->num == 0){//找下一个人head = head->next;if (head->num != 0){printf("没有退出的人为:%d\n", head->num);break;}}system("pause");return 0;
}
7.写一个函数建立一个有3名学生的数据的单项动态链表
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{int num;struct node* next;
}node;
//创建链表:一个含有N个节点的单向链表,返回头节点的指针
node* Creat(int n)
{//创建一个头节点node* head = (node*)malloc(sizeof(node));head->num = 0;head->next = NULL;node* p = head;//创建数据为1-N的节点for (int i = 1; i <= n; ++i){node* newNode = (node*)malloc(sizeof(node));newNode->num = i;newNode->next = NULL;p -> next = newNode;p = p->next;}return head;
}
//打印链表数据
void PrintNote(node* next)
{//第一个数据为head->nextnode* p = head->next;while (p != NULL){printf("node %d\n", p->num);p = p->next;}
}
void Del(node* head, int val)
{node* prev = head;node* p = head->next;//遍历链表,找到需要的删除的节点while (p != NULL){if (p->num == val){prev->next = p->next;free(p);break;}else{prev = p;p = p->next;}}
}
int main()
{node* head = Creat(10);int n;printf("当前所有链表的所有节点:>\n");PrintNode(head);printf("请输入需要删除的节点编号:\n");scanf("%d", &n);//删除之后链表的节点printf("删除之后链表的节点:>\n");Del(head, n);system("pause");return 0;
}
8.链表的插入 newNode = p->next p->next = newNode
#include <stdio.h>
#include <stdlib.h>
//定义节点
typedef struct node
{int num;struct node* next;
}node;
void Insert(node* node, int n)
{//创建节点node* newNode = (node*)malloc(sizeof(node));newNode->num = n;//连接newNode->next = node->next;p->next = newNode;
}
node* Creat(int n)
{//创建含有N个有效数据的节点//创建一个带头的链表node* head = (node*)malloc(sizeof(node));head->num = 0;head->next = NULL;node* p = head;//创建有效数据的节点for (int i = 1; i <= n; ++i){node* newNode = (node*)malloc(sizeof(node));newNode->num = i;newNode->next = NULL;p->next = newNode;p = p->next;}return head;
}
void PrintNode(node* head)
{//从第一个有效数据开始打印node* p = head->next;while (p != NULL){printf("node:%d\n", p->num);p = p->next;}
}
int main()
{int n;node* head = Creat(10);printf("未插入数据之前的链表:>\n");PrintfNode(head);printf("请输入需要插入的数据:>\n");scanf("%d", &n);Insert(head, n);printf("插入数据之后的链表结构:>\n");PrintNode(head);system("pause");return 0;
}
9.创建要求:从控制台输入数据,进行链表创建
输出:输出每一个数据
删除:指定数据的值
#include <stdio.h>
#include <stdlib.h>
//定义节点
typedef struct node
{int num;struct node* next;
}node;
//创建链表:从控制台输入数据
node* Creat()
{//先创建一个头节点,不存放有效数据node* head = (node*)malloc(sizeof(node));head->next = NULL;head->num = 0;node* p = head;printf("创建一个含有%d个数据的单链表", CNT);printf("请输入%d个数据", CNT);for (int i = 0; i < CNT; ++i){int n;scanf("%d", &n);node* newNode = (node*)malloc(sizeof(node));newNode->num = n;newNode->next = NULL;//链表p->next = newNode;p = p->next;}return head;
}
//打印链表
void PrintNode(node* head)
{node* p = head->next;while (p != NULL){printf("node:%d\n", p->num);p = p->next;}
}
//删除节点
void Del(node* head, int val)
{//遍历链表,找到待删除的位置node* p = head->next;node* prev = head;while (p != NULL){if (p->num == val){prev->next = p->next;free(p);break;}else{prev = p;p = p->next;}}
}
//插入节点
void Insert(node* p, int val)
{node* newNode = (node*)malloc(sizeof(node));newNode->num = val;newNode->next = p->next;p->next = newNode;
}
int main()
{printf("创建链表:\n");node* head = Cread();printf("创建链表结束:\n");printf("初始链表:\n");PrintNode(head);printf("请输入需要查询的链表:\n");int n;scanf("%d", &n);Insert(head, n);printf("插入数据之后,链表的所有数据:\n");PrintNode(head);printf("请输入要要删除的数据:\n");scanf("%d", &n);Del(head, n);printf("删除数据 %d 之后,链表的所有数据:\n",n);PrintNode(head);system("pause");return 0;
}
10.合并:把b的第一个节点连接到a的最后一个节点上
排序:选择排序:每次选择一个学号最小的,把它放在未排序节点的第一个位置
#include <stdio.h>
#include <stdlib.h>
//定义结构体
#define NUM 5
typedef struct node
{int num;float score;struct node* next;
}node;
node* creat()
{printf("请输入%d个数据:学号 成绩\n", NUM, 5);node* head = NULL;for (int i = 0; i < NUM; ++i){int num;float score;scanf("%d %f", &num, &score);//创建节点node* newNode = (node*)malloc(sizeof(node));newNode->num = num;newNode->score = score;newNode->next = NULL;//插入到已有的链表//判断当前是否为链表if (head == NULL){head = tail = newNode;}else{//把新的节点插入到尾节点后面tail->next = newNode;tail = newNode;}}return head;
}
//合并排序两个链表
node* MergeList(node* a, node* b)
{//合并 把b链表连接到a的最后一个节点node* head = a;while (head->next != NULL){head = head->next;}head->next = b;head = a;node* prev = a//排序、选择排序while (prev->next != NULL){//每次从未排序的节点中,选择一个学号最小的//放在第一个未排序节点的位置node* cur = prev->next;while (cur){if (prev->num->cur->num){//把学号小的数据往前移动int num = prev->num;float score = prev->score;prev->num = cur->num;prev->score = cur->score;cur->num = num;cur->score = score;}cur = cur->next;}prev = prev->next;}return head;
}
void PrintNode(node* a)
{while (a != NULL){printf("学号:%d 成绩 %f", a->num, a->score);a = a->next;}
}
int main()
{node* a = creat();node* b = creat();printf("链表a的数据:\n");PrintNode(a);printf("链表b的数据:\n");PrintNode(b);printf("合并a和b");a = mergeList(a, b);PrintNode(a);system("pause");return 0;
}
11.删除另一个链表中的所有节点
删除a和b中学号相同的节点的数据
删除:遍历b中的每一个节点
对于每一个b中的节点
依次遍历a中的每一个节点
比较当前遍历到的a中的节点
比较当前遍历到的a中的节点
和遍历到b中的节点
如果相同,删除
不相同,向后继续遍历
#include <stdio.h>
#include <stdlib.h>
#define LEN 20
typedef struct node
{int num;char name[LEN];struct node* next;
}node;
node* del(node* a, node* b)
{node* head = a;//遍历b中的每一个节点while (b){//从a的表头开始遍历node* prev = a;node* cur = prev->next;//用头节点和b当前指向的节点进行比较if (prev->num == b->num){prev->next = NULL;//更新表头head = cur;}//用非头节点和b当前指向的节点进行比较else{while (cur){if (cur->num == b->num){//删除当前节点prev->next = cur->next;cur->next = NULL;break;}else{//继续向后遍历prev = cur;cur = cur->next;}}}//处理b的下一个节点b = b->next;}return head;
}
void printNode(node* head)
{while (head){printf("%d-->%s\n", head->num, head->name);head = head->next;}
}
int main()
{//建立链表node a[5] = { { 3, "zhao" }, { 4, "li" }, { 15, "wang" }, { 10, "chen" }, { 8, "ren" } };node b[3] = { { 8, "ren" }, { 3, "zhang" }, { 12, "wang" } };for (int i = 0; i < 5; ++i){a[i].next = &a[i + 1];}a[4].next = NULL;for (int i = 0; i < 3; ++i){b[i].next = &b[i + 1];}b[2].next = NULL;printf("链表a:\n");printNode(a);printf("链表b:\n");printNode(b);//删除操作node* head = del(a, b);printf("删除之后的链表:\n");printNode(head);system("pause");return 0;
}
12.建立链表
结构体:学号 姓名 性别 年龄
根据年龄删除
可能有多个年龄相同的数据,也可能没有
删除为20
#include <stdio.h>
#include <stdio.h>
#define LEN 20
typedef struct node
{int num;char name[LEN];char gender[LEN];int age;struct node* next;
}node;
node* del(node* a)
{int age;printf("请输入需要删除的年龄:\n");scanf("%d", &age);//遍历删除node* prev = NULL;node* next;node* cur = a;node* head = a;while (cur){if (cur->age == age){//当前节点需要删除//头节点if (prev == NULL){//更新头节点head = cur->next;}//非头节点else{prev->next = cur->next;}//查看下一个节点cur = cur->next;}else{//当前节点不需要删除prev = cur;cur = cur->next;}}
}
void printNode(node* head)
{while (head){printf("%d %s %s %d\n", head->num, head->name, head->gender, head->age);head = head->next;}return head;
}
int main()
{node arr[] = { { 1, "wang", "male",15 }, { 2, "zhang", "female",20 }, { 3, "li", "male",21 }, { 4, "chen", "male",22 }, { 5, "cheng", "male",23 } };//建立链表for (int i = 0; i < 5; ++i){arr[i].next = &arr[i + 1];}arr[4].next = NULL;printf("链表的所有数据:\n");printNode(arr);node* head = del(arr);printf("删除之后链表的剩余数据:\n");printNode(head);system("pause");return 0;
}
第十章
1.C语言中指针是灵魂
指针、操作、变量、数组、函数、结构体、文件
文件指针访问文件的好处:屏蔽软件和硬件之间的联系
文件指针:实质上是个结构体的指针
2.文件的打开:
文件的关闭:关闭了文件和指针之间的联系
为什么要这些操作:
程序/软件--->缓冲区(iobuf)--->文件/硬件 程序/软件<----缓冲区(iobuf)<----文件/硬件
3.
#include <stdio.h>
#include <stdlib.h>
int main()
{FILE *fp = NULL;fp = fopen("text.txt", "w");if (fp == NULL){printf("打开失败\n");return -1;}//输入字符串并进行转换char ch;while ((ch = getchar() != '!')&&(ch != EOF)){if (ch >= 'a'&&ch <= 'z'){ch -= 32;//小写转大写}fputc(ch, fp);}//关闭文件fclose(fp);system("pause");return 0;
}
4.将两个文件进行合并
#include <stdio.h>
#include <stdlib.h>
void OpenFile(FILE **fpa, FILE **fpb,FILE **fpc)
{*fpa = fopen("4.txt", "r");if (fpa == NULL){printf("打开失败\n");exit(1);}*fpb = fopen("4.txt", "r");if (fpb == NULL){printf("打开失败\n");exit(1);}*fpc = fopen("4.txt", "r");if (fpc == NULL){printf("打开失败\n");exit(1);}
}
void GetBufferChar(FILE *fpa, FILE *fpb,char *buffer)
{fgets(buffer, 1024, fpa);int len = strlen(buffer);fgets(buffer + len, 1024 - len, fpb);
}
void SortBufferChar(char *buffer)
{//冒泡排序int n = strlen(buffer);for (int i = 0; i < n - 1; n++){for (int j = 0; j < n - i - 1; ++j){if (buffer[j]>buffer[j + 1]){int tmp = buffer[j];buffer[j] = buffer[j + 1];buffer[j + 1] = tmp;}}}
}
void SaveFile(FILE *fpc, char *buffer)
{fputs(buffer, fpc);}
void CloseFile(FILE *fpa, FILE *fpb, FILE *fpc)
{fclose(fpa);fclose(fpb);fclose(fpc);
}
void main()
{FILE *fpa, *fpb, *fpc;OpenFile(&fpa, &fpb, &fpc);char buffer[1024] = { 0 };GetBufferChar(fpa, fpb, buffer);SortBufferChar(buffer);SaveFile(fpc, buffer);CloseFile(fpa, fpb, fpc);system("pause");
}
5.
#include <stdio.h>
#include <stdlib.h>
typedef struct Student
{int num;//学号char name[32];//姓名int score[3];//三门课程成绩float avg;//三门课程平均分
}Student;
int main()
{Student stu[5];//创建五个学生的结构体for (int i = 0; i < 5; ++i){printf("num name score1 score2 score3\n");scanf("%d %s %d %d %d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);//计算平均分stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2])/3.0;}FILE *fp = fopen("stud.txt", "w");if (fp == NULL){printf("打开文件失败\n");return -1;}//将数据写入文件for (int i = 0; i < 5; ++i){fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2],stu[i].avg);}fclose(fp);system("pause");return 0;
}
6. 读入数据 - stud.txt
排序数据
写入数据
#include <stdio.h>
#include <stdlib.h>
typedef struct Student
{int num;//学号char name[32];//姓名int score[3];//三门课程成绩float avg;//三门课程平均分
}Student;
void ReadData(Student *stu)
{FILE *fp = fopen("stud.txt", "r");if (fp == NULL){printf("打开文件失败\n");return -1;}//读入数据for (int i = 0; i < 5; ++i){fscanf("%d %s %d %d %d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);//计算平均分stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;}//关闭文件fclose(fp);
}
void SortData(Student *stu)
{Student tmp_stu;int size = sizeof(tmp_stu);//冒泡排序for (int i = 0; i < n - 1; ++i){for (int j = 0; j < n - i - 1; ++j){if (stu[j].avg < stu[j + 1].avg){//交换结构体数据排序memcpy(&tmp_stu, &stu[j], size);memcpy(&stu[j], &stu[j + 1], size);memcpy(&stu[j + 1], &tmp_stu, size);}}}
}
void WriteData(Student *stu)
{FILE *fp = fopen("stu_sort.txt", "w");if (fp == NULL){printf("打开文件失败\n");return -1;}//写入数据for (int i = 0; i < 5; ++i){fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2],stu[i].avg);}//关闭数据fclose(fp);
}
int main()
{Student stu[5];//创建五个学生的结构体ReadData(stu);SortData(stu,5);WriteData(stu);system("pause");return 0;
}
7.
#include <stdio.h>
#include <stdlib.h>
typedef struct Student
{int num;//学号char name[32];//姓名int score[3];//三门课程成绩float avg;//三门课程平均分
}Student;
void InputData(Student *stu)
{printf("请输入新学生的成绩信息:>\n");printf("name score1 cscore2 score3 :\n");scanf("%d %s %d %d %d", &(stu->num), stu->name, &(stu->score[0]), &(stu->score[1]), &(stu->score[2]));stu->avg = (stu->score[0] + stu->score[1] + stu->score[2]) / 3.0;
}
void ReadData(Student **stu)
{FILE *fp = fopen("stud.txt", "r");if (fp == NULL){printf("打开文件失败\n");exit(-1);}//读入数据for (int i = 0; i < 5; ++i){fscanf("%d %s %d %d %d", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);//计算平均分stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;}//关闭文件fclose(fp);
}
void InsertData(Student *old_stu,Student *new_stu,int n)
{int pos = 0;while (pos < n){if (new_stu->avg>old_stu[pos].avg){break;}pos++;}//移动数据for (int i = n; i > pos; --i){memcpy(&old_stu[i], &old_stu[i - 1], sizeof(Student));}//在pos位置把新学生的数据插入memcpy(&old_stu[pos], new_stu, sizeof(Student));
}
void WriteData(Student *stu)
{FILE *fp = fopen("stu_new_sort.txt", "w");if (fp == NULL){printf("打开文件失败\n");exit(-1);}//写入数据for (int i = 0; i < 6; ++i){fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].avg);}//关闭数据fclose(fp);
}
int main()
{Student new_stu;//新学生结构体Student old_stu[6];InputData(&new_stu);ReadData(old_stu);InsertData(&old_stu, &new_stu,5);WriteData(old_stu);system("pause");return 0;
}
8.
#include <stdio.h>
#include <stdlib.h>
typedef struct Student
{int num;//学号char name[32];//姓名int score[3];//三门课程成绩float avg;//三门课程平均分
}Student;
static count;
void InputData(Student *stu)
{printf("请输入新学生的成绩信息:>\n");printf("name score1 cscore2 score3 :\n");scanf("%d %s %d %d %d", &(stu->num), stu->name, &(stu->score[0]), &(stu->score[1]), &(stu->score[2]));stu->avg = (stu->score[0] + stu->score[1] + stu->score[2]) / 3.0;
}
void ReadData(Student **stu)
{FILE *fp = fopen("stud.txt", "w");if (fp == NULL){printf("打开文件失败\n");exit(-1);}//读出数据的条数int count;fscanf(fp, "%d\n", &count);*stu = (Student*)malloc(sizeof(Student)*(count + 1));Student *pstu = *stu;//读入数据for (int i = 0; i < count; ++i){fscanf("%d %s %d %d %d", &pstu[i].num, pstu[i].name, &pstu[i].score[0], &pstu[i].score[1], &pstu[i].score[2]);//计算平均分pstu[i].avg = (pstu[i].score[0] + pstu[i].score[1] + pstu[i].score[2]) / 3.0;}//关闭文件fclose(fp);//释放空间,避免造成泄漏free(stu);
}
void InsertData(Student *old_stu, Student *new_stu, int n)
{int pos = 0;while (pos < n){if (new_stu->avg>old_stu[pos].avg){break;}pos++;}//移动数据for (int i = n; i > pos; --i){memcpy(&old_stu[i], &old_stu[i - 1], sizeof(Student));}//在pos位置把新学生的数据插入memcpy(&old_stu[pos], new_stu, sizeof(Student));
}
void WriteData(Student *stu)
{FILE *fp = fopen("stu_new_sort.txt", "w");if (fp == NULL){printf("打开文件失败\n");exit(-1);}//写入数据fprintf(fp, "%d", count + 1);//先写出记录的条数for (int i = 0; i < count+1; ++i){fprintf(fp, "%d %s %d %d %d %f\n", stu[i].num, stu[i].name, stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].avg);}//关闭数据fclose(fp);}
int main()
{Student new_stu;//新学生结构体Student old_stu[6];InputData(&new_stu);ReadData(&old_stu);InsertData(&old_stu, &new_stu, count);WriteData(old_stu);system("pause");return 0;
}
9.
#include <stdio.h>
#include <stdlib.h>
//employee.txt 读出数据
//抽出职工名字和工资
//输出到一个新的文件
typedef struct employee
{int num;char name[32];char sex[4];int age;char addr[128];int salary;char health[10];char classes[10];
}employee;
int main()
{employee emp;FILE *fpin = fopen("employee.txt", "w");if (fpin == NULL){printf("打开employee.txt文件失败\n");return -1;}FILE *fpout = fopen("emp_salary.txt", "w");if (fpout == NULL){printf("打开emp_salary.txt文件失败\n");fclose(fpin);return -1;}//读出数据并抽出相应的信息进行写入while (!feof(fpin)){int count = fscanf(fpin, "%d %s %s %d %s %d %s %s", &emp.num, emp.name, emp.sex, &emp.age, emp.addr, &emp.salary, emp.health, emp.classes);if (count == -1){break;}fprintf(fpout, "%s %d\n", emp.name, emp.salary);}//关闭文件fclose(fpin);fclose(fpout);system("pause");return 0;
}
10.从职工表中删除一个数据,在存到该文件中
从程序里面输入一个名字,再进行查找需要删除的用户
#include <stdio.h>
#include <stdlib.h>
typedef struct emp_salary
{char name[32];int salary;
}emp_salary;
int main()
{emp_salary es[100];FILE *fp = fopen("emp_salary.txt", "w");if (fp == NULL){printf("打开emp_salary.txt文件失败\n");return -1;}int i = 0;while (!feof(fp)){fscanf(fp, "%s %d", es[i].name, &es[i].salary);if (count == 1){break;}i++;}//关闭文件fclose(fp);//输入名字进行删除char name[32] = { 0 }; printf("请输入要删除的职工的姓名:>");scanf("%s", &name);fp = fopen("emp_salary.txt", "w");if (fp == NULL){printf("打开emp_salary.txt文件失败\n");return -1;}for (int j = 0; j < i; ++j){if (strcmp(name, es[j].name) == 0){continue;}fprintf(fp, "%s %d\n", es[j].name, es[j].salary);}//关闭文件fclose(fp);system("pause");return 0;
}
11. 从键盘上输入若干个字符
存储到磁盘文件中
从文件中读入数据
将小写字母转成大写字母
输出到屏幕上
#include <stdio.h>
#include <stdlib.h>
void ToUpper(char *str)
{while (*str != '\0'){//小写字母if (*str >= 'a'&&*str <= 'z'){*str -= 32;}//继续判断下一个字母//直到所有判断完毕,退出程序str++;}
}
int main()
{FILE *fp = fopen("letter.txt", "w");if (fp == NULL){printf("打开letter.txt文件失败\n");return -1;}//输入字符串然后写入文件char buf[128] = { 0 };while (1){printf("请输入字符串(如果输入exit则退出输入):>\n");gets(buf);if (strcmp("exit", buf) == 0){break;}fprintf(fp, "%s\n", buf);}//关闭文件fclose(fp);//读出数据,进行转换FILE *fp = fopen("letter.txt", "r");if (fp == NULL){printf("打开letter.txt文件失败\n");return -1;}while (!feof(fp)){memset(buf, 0, 128);fgets(buf, 128, fp);ToUpper(buf);printf("%s\n", buf);}//关闭文件fclose(fp);system("pause");return 0;
}
C语言(谭浩强第5版)课后习题知识总结相关推荐
- C语言程序设计(谭浩强第五版)——习题
C语言程序设计(谭浩强第五版)--习题 第3章 最简单的C程序设计--顺序程序设计 第4章 选择结构程序设计 第5章 循环结构程序设计 第6章 利用数组处理批量数据 第3章 最简单的C程序设计--顺序 ...
- C语言程序设计第五版 谭浩强 第四章 课后习题 答案
谭浩强C语言程序设计第五版 第4章 课后习题 答案 点我看视频讲解+可运行源码 记得一键三连哦 第四章 选择结构程序设计 1. 什么是算术运算?什么是关系运算?什么是逻辑运算? [答案解析] 算熟运算 ...
- C程序设计谭浩强第五版课后答案 第三章习题答案
C语言程序设计谭浩强第五版课后答案第三章 1.假如我国国民生产总值的年增长率为7%, 计算10年后我国国民生产总值与现在相比增长多少百分比.计算公式为p=(1+r)np = (1+r)^np=(1+r ...
- 有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母,小写字母,数字,空格以及其他字符的个数。谭浩强《C程序设计课后习题》第6章第10题。
题目 本题是谭浩强<C程序设计课后习题>第6章第10题. 题目:有一篇文章,共有3行文字,每行有80个字符.要求分别统计出其中英文大写字母,小写字母,数字,空格以及其他字符的个数. 以下是 ...
- C语言谭浩强第5版章节编程题
本文用来练习谭浩强章节练习题,慢慢更新.有需要解答的在下边留言第一时间回复. 第一章 1-6 编写一个程序,输入3个数a,b,c,输出最大值. #define _CRT_SECURE_NO_WARNI ...
- 《C语言程序设计》谭浩强-学习笔记以及课后习题答案(考前复习/考研/专升本)
此笔记是几年前为了本人考试而学而写,今日回首感慨良多,便把尘封多年在旧电脑中的学习笔记翻出来分享给大家 此笔记参考书籍: <C语言程序设计>谭浩强 根据前九章内容主要知识点进行梳理 如果有 ...
- c语言 谭浩强第五版第五章习题第17题 乒乓球比赛
两个乒乓球队进行比赛,各出三人.甲队为A,B,C3人,乙队为X,Y,Z3人.已抽签决定比赛名单.有人向队员打听比赛的名单,A说他不和X比,C说他不和X,Z比,请编程序找出3对赛车的名单. #inclu ...
- c语言谭浩强第五版---全书笔记+习题(一)
写在开始之前,适合有一点基础的人复习使用!!!!!!! 写在开始之前,适合有一点基础的人复习使用!!!!!!! 写在开始之前,适合有一点基础的人复习使用!!!!!!! 常用的头部文件 #include ...
- C语言谭浩强第三版第九章例题及课后题:预处理命令
目录 9.1定义一个带参数的宏,使两个参数的值互换 9.2输入两个整数,求它们相除的余数 9.3求三角形面积 9.4(5)判断闰年 9.5分析下面的宏所定义的输出格式 9.6设计输出实数的格式 9.7 ...
- C语言谭浩强第三版第十二章例题及课后题:位运算
eg12.1取一个整数a从右端开始的4~7位 0000...000000 0 1111...111111 ~0 1111...110000 ~0<< ...
最新文章
- 堆晶结构_橄榄岩的特殊问题
- SAP零售行业解决方案初阶 7 - 自动补货
- Kmeans聚类算法详解
- Acwing900. 整数划分[计数类dp]:完全背包解法
- IBM HyperLedger fabric 详解
- 对南昌杀人案的一些看法
- 电商迅猛发展是利大于弊,还是弊大于利?
- java 如何添加背景音乐_Java程序怎样添加背景音乐?
- 苹果笔记本python爬取网页后怎么存下来_python 爬取csdn网页并保存博客到本地
- 目前最全的动画名称中英对照表
- 5G的调制方式,到底是怎么实现的?
- Epicor10自定义更新
- 输出今天是星期几并计算n天后的日期(万年历)
- 核心路由器十项性能指标(转)
- wim工具扫描linux磁盘,WimTool Pro(WIM映像处理工具)
- 如何才能修炼成一名不可替代的程序员?
- 10G PON 进入到全面部署阶段
- 高德地图两个多边形区域检测重叠解决方案
- 利用conda安装包、卸载包、升级包、查看包信息等操作
- 小米手机ADB删除系统应用去广告
热门文章
- mysql读写分离的完整配置
- 不得不批,铁道部售票网
- 获取猫眼电影所有城市信息
- 为什么HikariCP是性能最好的数据库连接池?
- html5 视频录制上传视频,怎么上传视频(手把手教你怎么在今日头条录制及上传视频)...
- python爬取大众点评某城市美食类数据
- Leetcode 584 寻找用户推荐人(SQL)
- ubuntu远程桌面软件
- 【LaTeX】IEEE会议模板中插入双栏图片(解决报错:Undefined control sequence. \subfloat
- 在计算机网络中 使用术语 来表示,计算机一级填空题复习资料