大家好,欢迎来到IT知识分享网。
《啊哈C语言——逻辑的挑战》学习笔记
第一章 梦想启航
第1节 让计算机开口说话
1、基础知识
1)计算机“说话”的两种方式
格式:printf(“”);
注意:
框架:
#include<stdio.h> #include<stdlib.h> int main() {
return 0; }
4)让计算机“暂停一下”
语句:
system("pause");
5)换行
语句:“\n”
第2节 多彩一点
1、设置命令行的背景颜色与文字颜色
详细用法:
示例
#include<stdio.h> #include<stdlib.h> int main() {
system("color f5"); printf("wa wa wa"); system("pause"); return 0; }
2、相关颜色代码
第3节 让计算机做加法
1、过程
输入——存储——计算——输出
2、基础知识
1)赋值号
符号:=
作用:将右边内容赋给左边
2)“小房子”
格式:
int a,b,c;
3)代码展示
int a,b,c; a=1; b=2; c=a+b;
过程:
①先将a+b算出来;
②将a+b的值赋给“=”左边的c。
4)“讨债的”
代码:
printf("%d",c);
作用:
将逗号右边“小房子”c中的数值“索取”出来。
5)加法的完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a,b,c; a = 1; b = 2; c = a + b; printf("%d", c); system("pause"); return 0;
第4节 数字的家——变量
1、基础知识
1)小数=浮点数
2)变量
“小房子”又叫变量。
3)变量类型/数据类型
4)赋值规则
第5节 数据输出——我说咋地就咋地
1、基础知识
1)将整个算数等式输出
代码展示:
#include<stdio.h> #include<stdlib.h> int main() {
int a,b,c; a-1; b=2; c=a+b; printf("%d+%d=%d",a,b,c);//相当于a+b=c system("pause"); return 0; }
分析:
%d按顺序依此向引号后面的变量“讨债”。
2)注意
- printf语句只会输出双引号里面的部分,双引号之外的部分只是对双引号内的部分起到补充说明的作用。
- 通常双引号内部“%d“的个数,和后面变量的个数是相等的。
第6节 数据输入——我说算啥就算啥
1、基础知识
3)输入语句的两种写法
写法一: scanf("%d",&a); scanf("%d",&b); 写法二: scanf("%d%d",&a,&b);
注意:
第二种写法更简便,两个“%d”之间不需要空格,“&a”和“&b”之间用逗号隔开。
4)从键盘读入两个数,输出这两个数之和的完整代码
#include<stdio.h>. #include<stdlib.h> int main() {
int a,b,c; scanf("%d%d",&a,&b); c=a+b; printf("%d+%d=%d",a,b,c); system("pause"); return 0; }
第7节 究竟有多少种房子
1、基础知识
1)C语言常用的数据类型
| 数据类型名称 | 用来存放哪种数据 |
|---|---|
| int | 整数 |
| float | 浮点数 |
| double | 极大和极小的浮点数 |
| char | 字符 |
2)float和double的区别
printf("%.15f", a);
代码中“%”和“f”之间的“.15”表示保留小数点后15位(四舍五入)。
3)字符数据类型——char
格式:
char a = 'x';
t = a; a = b; b = t;
完整代码:
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, t; scanf("%d%d", &a, &b): t = a; a = b; b = t; printf("%d %d", a, b); system("pause"); return 0; }
通过创建一个临时变量t,将变量a的值暂时存储起来,然后将b的值赋给a,再将t的值(原a的值)赋给b,从而完成交换。
方法二:(差值法)
Key:
a = b - a;//a与b的差值 b = b - a;//b = a;b减去差值就为a a = a + b;//a再加上差值就为b,然后将b的值赋给a
完整代码:
#include<stdio.h> #include<stdlib.h> int main() {
int a, b; scanf("%d%d", &a, &b); a = b - a; b = b - a; a = b + a; printf("%d %d", a, b); return 0; }
第8节 天哪!这怎么能看懂
1、代码规范
- 使用Tab来调整代码格式
2、注释的种类及作用
- “//”——单行注释
- “//”——多行注释
- 解释说明本行代码的作用
- 暂时不需要
第二章 较量才刚刚开始
第1节 大于、小于还是相等
1、关系运算符
| == | 相等 |
|---|---|
| > | 大于 |
| < | 小于 |
| >= | 大于等于 |
| <= | 小于等于 |
| != | 不等于 |
第2节 判断正数
1、算法
本质:
解决问题的方法和步骤。
2、条件语句(if语句)
问题:
如何判断一个数是否为正数,负数,0,满足条件分别输出”yes”,“no”,“0”
if语句的三种表示方法:
//1 if (a>0) {
printf("yes");} //2 if (a>0) printf("yes");//当且仅当条件成立时只需执行一条语句才可省略{} //3 if (a>0) printf("yes");
3、完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a;//第一步,创建一个变量用来存储将要判断的整数 scanf("%d", &a);//第二步,输入一个整数 if(a > 0) printf("yes");//第三步,判断输入的整数是否为正数,若是,则输出yes if(a < 0) printf("no");//第四步,判断输入的整数是否为负数,若是,则输出no if(a == 0) printf("0");//第五步,判断输入的整数是否为0,若是,则输出0 return 0; }
第3节 偶数判断
1、基础知识
1)问题
判断一个数是否是偶数
2)分析
偶数就是能够被2整除的数,如果一个数除以2的余数为0,那么这个数就是偶数。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if(a % 2 == 0) printf("yes"); if(a % 2 != 0) printf("no"); return 0; }
2、一起来找茬
1)问题
判断一个数是否为7的倍数
2)分析
7的倍数就是能够被7整除的数,如果一个数除以7的余数为0,那么这个数就是7的倍数
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if(a % 7 == 0) printf("yes"); if(a % 7 != 0) printf("no"); return 0; }
3、更进一步,动手试一试
1)问题
如何判断一个数的末尾是不是0呢?如果是则输出yes(例如120),不是则输出no(例如1234)。
2)分析
如果一个数除以10的余数为0,则这个数的末尾是0。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if(a % 10 == 0) printf("yes"); if(a % 10 != 0) printf("no"); return 0; }
4)拓展
第4节 神器else
1、基础知识
1)语法格式
if (条件) {
语句 1; 语句 2; 语句 ……; } else {
语句 1; 语句 2; 语句 ……; }
当条件为真的时候执行if后面的语句;当条件为假的时候执行else后面的语句。
2、一起来找茬
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if(a % 10 == 7) printf("yes"); else printf("no"); return 0; }
3、更进一步,动手试一试
1)问题
从键盘键入一个正整数,让计算机判断这个数是否为一位数(1~9)。如果是则输出yes,否则输出no。
2)分析
如果一个数是一位数,则这个数除以10恒为0。否则,这个数不是一位数。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if(a / 10 == 0) printf("yes"); else printf("no"); return 0; }
第5节 请告诉我谁大
1、基础知识
1)问题
如何让计算机判断两个数中,谁更大?
2)分析
定义3个变量,a和b用来存放输入的两个数,c用来存放a和b中较大的那个。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, c; scanf("%d%d", &a, &b); if(a > b) {
c = a; } else {
c = b; } printf("%d", c); return 0; }
2、更进一步,动手试一试
#include<stdio.h> #include<stdlib.h> int main() {
int a, b;//定义两个变量 scanf("%d%d", &a, &b);//输入两个数 if(a % b == 0)//如果a能被b整除,则a是b的倍数,b是a的约数,输出yes {
printf("yes"); } else {
printf("no"); } return 0; }
逻辑挑战2:3个数怎么办
1、基础知识
//方法一:创建新变量存储较大的值 #include<stdio.h> #include<stdlib.h> int main() {
int a, b, c, d;//a,b,c用来存放输入的值,d用来存放较大的值 scanf("%d%d%d", &a, &b, &c); if(a > b) {
d = a; } else {
d = b; } if(c > d) {
d = c; } printf("%d", d);//输出d——最大的值 return 0; } //方法二:先分别比较a和b,以及a和c的关系,再b,再c…… #include<stdio.h> #include<stdlib.h> int main() {
int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a >= b && a >= c) printf("%d", a); if(b >= a && b >= c) printf("%d", b); if(c > a && c > b) printf("%d", c);//若 if(c >= a && c >= b) printf("%d", c);则会输出两次值 return 0; }
2、更进一步,动手试一试
1)问题
从键盘输入一个年份(整数),判断这个年份是否为闰年,是则输出yes,不是则输出no。
2)分析
闰年的判定
能被4整除,但不能被100整除。
能被4整除,也能被400整除。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a; scanf("%d", &a); if((a % 4 == 0 && a % 100 != 0) || (a % 4 == 0 && a % 400 == 0)) {
printf("yes"); } else {
printf("no"); } return 0; }
逻辑挑战3:我要排序
1、基础知识
问题:
如何从键盘输入任意3个数,并将这3个数从大到小排序呢?
完整代码:
1)方法一:直接法
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, c; scanf("%d%d%d", a, b, c); if(a >= b && a >= c) printf("%d %d %d", a, b, c); if(a >= c && c > b) printf("%d %d %d", a, c, b); if(b > a && a >= c) printf("%d %d %d", b, a, c); if(b >= c && c > a) printf("%d %d %d", b, c, a); if(c > a && a >= b) printf("%d %d %d", c, a, b); if(c > b && b > a) printf("%d %d %d", c, b, a); return 0; }
2)方法二:换位法
分析:先将变量a与变量b和变量c以此比较,若b和c中的值大于a中的值,则与a进行交换,经过两次比较后,变量a中的值最大。然后将b和c进行比较,若b<c,则交换,确保b为次大。最终将最大的数放在小房子a中,次大的数放在小房子b中,最小的数放在小房子c中
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, c, t; scanf("%d%d%d", &a, &b, &c); if(a < b) {
t = a; a = b; b = t; } if(a < c) {
t = a; a = c; c = t; } if(b < c) {
t = b; b = c; c = t; } printf("%d %d %d", a, b, c); return 0; }
2、一起来找茬
奇数a的两种判断方法:
- a % 2 != 0
- a % 2 == 1
第6节 运算符总结
基础运算符
| 名称 | 作用 |
|---|---|
| + | 加 |
| – | 减 |
| * | 乘 |
| / | 除 |
| > | 大于 |
| < | 小于 |
| == | 等于 |
| >= | 大于等于 |
| <= | 小于等于 |
| != | 不等于 |
| && | 与 |
| 或 | |
| ! | 非 |
第7节 1 > 2 究竟对不对
if (1) {
printf("yes"); } else {
printf("no"); }//输出yes if (-5) {
printf("yes"); } else {
printf("no"); }//输出yes if (0) {
printf("yes"); } else {
printf("no"); }//输出no
第8节 讨厌的嵌套
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a >= b) {
if(a >= c) {
printf("%d", a); } else {
printf("%d", c); } } else//a < b {
if(b >= c) {
printf("%d", b); } else {
printf("%d", c); } } return 0; }
简化版本:
#include<stdio.h> #include<stdlib.h> int main() {
int a, b, c; scanf("%d%d%d", &a, &b, &c); if(a >= b) if(a >= c) printf("%d", a); else printf("%d", c); else//a >= b 不成立的情况 if(b >= c) printf("%d", b); else printf("%d", c); return 0; }
总结:
- else的匹配采用就近原则
- if-else“复合语句”在外层看来本质上就是一条if-else语句
第9节 if-else语法总结
总结:
1、当if()括号内的关系表达式成立的时候,就执行if()后面的{}中的内容,不成立的时候则执行else后面{}中的内容。
if (关系表达式) {
语句; 语句; …… } else {
语句; 语句; …… }
2、当{}内的语句只有一条的时候,{}可以省略
if (关系表达式) 语句; else 语句;
第4章 重量级选手登场
第1节 永不停止的哭声
1、基础知识
1)问题
如何让计算机做重复的事情。
2)while语句
#include<stdio.h> #include<stdlib.h> int main() {
system("color 2"); while(1) {
printf("wa"); } return 0; }
该程序会永无止境的输出“wa”。
3)语法
第2节 我说几遍就几遍
1、基础知识
假设让计算机打印1~100,我们要让关系表达式在前100次是成立的,然后在第101次时就不成立了。
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; while(a <= 100) {
printf("%d ", a); a = a + 1; } return 0; }
第3节 if对while说:我对你很重要
1、基础知识
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; while(a <= 100) {
if (a % 3 != 0) printf("%d ", a); a = a + 1; } return 0; }
- 两个if条件判断——7的倍数——末尾含7的数
- 末尾含7的数其实就是这个数的个位为7,也就是这个数除以10的余数为7
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; while(a <= 100) {
if (a % 7 == 0 || a % 10 == 7) printf("%d ", a); a = a + 1; } return 0; }
第4节 求和!求和!!求和!!!
1、基础知识
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 0;//初始值为0,刚开始水果篮子里什么都没有 int i = 1; while(i <= 100) {
a = a + i;//装苹果的a i = i + 1; //搬运苹果的i } printf("%d", a); return 0; }
3)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1;//a的初始值要为1,不然0乘以任何数还是0 int i = 1; while(i <= 10) {
a = a * i; i = i + 1; } printf("%d", a); return 0; }
3、更进一步,动手试一试
1)问题
输入一个整数n(1<=n<=9),求n的阶乘。
2)分析
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; int i = 1; int n; scanf("%d", &n); while(i <= n) {
a = a * i; i = i + 1; } printf("%d", a); return 0; }
注意:
scanf语句中不能输入提示性文字,例如 scanf(“请输入n的阶乘数:%d”, &n); 是错误的!
逻辑挑战4:60秒倒计时开始
1、基础知识
3)完整代码
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 60; system("color 0a");//设置成黑底绿字 while(a >= 1) {
system("cls");//每次显示之前先清一次屏 printf("%d", a);//输出倒计时时间 Sleep(1000);//“等待”1s a = a - 1; } return 0; }
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
system("color f5");//白底紫字 int a = 59; printf("2:00"); Sleep(1000); while(a >= 0)//第一次1:59~1:00之间的循环 {
system("cls"); if(a < 10) {
printf("1:0%d", a); } else {
printf("1:%d", a); } Sleep(1000); a = a - 1; } a = 59;//初始化a的值 while(a >= 0)//第二次0:59~0:00之间的循环 {
system("cls"); if(a < 10) {
printf("0:0%d", a); } else {
printf("0:%d", a); } Sleep(1000); a = a - 1; } return 0; }
第6节 这个有点晕——循环嵌套来了
1、问题1——打印3行5列星号
1)分析
一共要输出15个星号,每打印5个星号就需要换一行。
2)方法
方法一:通过if语句控制打印换行
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 1; while(a <= 15) {
printf("*"); if(a % 5 == 0)//如果变量a的值恰好是5的倍数,换行 printf("\n"); a = a + 1; } return 0; }
方法二:循环嵌套
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; while(a <= 3) {
int b = 1;//每行开始都要初始化b的值 while(b <= 5) {
printf("*"); b = b + 1; } printf("\n");//每一行输入完5个星号后,换行 a = a + 1; } return 0; }
分析:
2、问题2——打印阶梯状星号
2)完整代码
#include<stdio.h> #include<stdlib.h> int main() {
int a = 1; while(a <= 5) {
int b = 1;//每行开始都要初始化b的值 while(b <= a) {
printf("*"); b = b + 1; } printf("\n");//每一行输入完a个星号后,换行 a = a + 1; } return 0; }
1)请尝试用while循环打印下面的图形
#include<stdio.h> #include<stdlib.h> int main() {
int n, a = 1; scanf("%d", &n); while(a <= n) {
int b = 1; while(b <= a) {
printf("%d ", a);//每行输出的是当前行数 b = b + 1; } printf("\n"); a = a + 1; } return 0; }
请尝试用while循环打印下面的图形
#include<stdio.h> #include<stdlib.h> int main() {
int n, a = 1, cnt = 1;//用来统计目前已输出的数字个数 scanf("%d", &n); while(a <= n) {
int b = 1; while(b <= a) {
printf("%d ", cnt);//输出目前是第几个数字 b = b + 1; cnt = cnt + 1; } printf("\n"); a = a + 1; } return 0; }
逻辑挑战5:奔跑的数字
1)问题
如果希望一个字母(假设这个字母是H)从屏幕的左边往右边跑,即第一秒时字母H在屏幕的第一行的最左边(也就是第一行第一列),第二秒时字母H在屏幕的第一行的第二列,第三秒时字母H在屏幕第一行的第三列,以此类推。
2)方法
方法一:初尝试
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
system("cls"); printf("H"); Sleep(1000); system("cls"); printf(" H"); Sleep(1000); system("cls"); printf(" H"); system("pause"); return 0; }
完整代码
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 0; while(a <= 2) {
system("cls"); int b = 1;//若b = 0,则会导致第一个字母前会出现空格 while(b <= a)//循环开始前,打印相应循环次数个空格数 {
printf(" "); b = b + 1; } printf("H"); Sleep(1000); a = a + 1; } return 0; }
利用while a循环来控制字母H一共需要走多少步,利用while b循环来控制字母H每走一步需要在字母H前面打印多少个空格
第7节 究竟循环了多少次
1、基础知识
1)代码
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 1; while(a <= 2) {
int b = 1; while(b <= 3) {
printf("OK "); b = b + 1; } a = a + 1; } return 0; }
逻辑挑战6:奔跑的小人
1、基础知识
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 0;//统计循环的次数,即奔跑的次数,也是打印空格的数量 int b; while(a <= 2) {
system("cls");//每次输出前先进行“清屏” b = 1; while(b <= a)//第一个小人的头打印0次空格,第二个小人的头打印1次空格,第三个小人的头打印2次空格 {
printf(" "); b = b + 1; } printf(" O\n"); b = 1; while(b <= a)//第一个小人的身体打印0次空格,第二个小人的身体打印1次空格,第三个小人的身体打印2次空格 {
printf(" "); b = b + 1; } printf("<H>\n"); b = 1; while(b <= a)//第一个小人的脚打印0次空格,第二个小人的脚打印1次空格,第三个小人的脚打印2次空格 {
printf(" "); b = b + 1; } printf("I I\n"); Sleep(1000);//打印完一个小人整体后,“等待”1s——控制小人奔跑的速度 a = a + 1; } return 0; }
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
int a = 20;//统计循环的次数,即奔跑的次数,也是打印空格的数量 int b; while(a >= 0) {
system("cls");//每次输出前先进行“清屏” b = 1; while(b <= a)//第一个小人的头打印20次空格,第二个小人的头打印19次空格,第三个小人的头打印18次空格 {
printf(" "); b = b + 1; } printf(" O\n"); b = 1; while(b <= a)//第一个小人的身体打印20次空格,第二个小人的身体打印19次空格,第三个小人的身体打印18次空格 {
printf(" "); b = b + 1; } printf("<H>\n"); b = 1; while(b <= a)//第一个小人的脚打印20次空格,第二个小人的脚打印19次空格,第三个小人的脚打印18次空格 {
printf(" "); b = b + 1;//不断地减少打印的空格数量 } printf("I I\n"); Sleep(100);//打印完一个小人整体后,“等待”1s——控制小人奔跑的速度 a = a - 1; } return 0; }
第八节 for隆重登场
1、基础知识
1) 语法
//以打印数字1~10为例 for(int a = 1;i <= 10;a++) {
printf("%d", a); }
2)特点
- 已知循环次数用for
- 未知循环次数用while
2、更进一步,动手试一试
1)请尝试用for循环打印下面的图形
#include<stdio.h> #include<stdlib.h> #include<windows.h> int main() {
for(int i = 1;i <= 5;i++)//菱形的上半部分 {
for(int k = 4;k >= i;k--)//在打印星号之前打印的空格数(与行数的关系) {
printf(" "); } for(int j = 1;j <= 2 * i - 1;j++)//行数与列数的关系:列数=2*行数-1 {
printf("*"); } printf("\n"); } int t = 7;//创建一个变量,用来控制菱形下部分的循环次数 for(int i = 1;i <= 4;i++)//菱形的下半部分 {
for(int j = 1;j <= i;j++) {
printf(" "); } for(int j = 1;j <= t;j++) {
printf("*"); } t = t - 2;//打印完一行星号后,下一行打印星号数量减2 printf("\n"); } return 0; }
分析:
- 图形整体无法找出规律,可拆分成几部分
- 找出行与列的关系
- 可引入新变量来满足规律
2、请尝试用for循环来打印一个九九乘法表
#include<stdio.h> #include<stdlib.h> int main() {
for(int i = 1;i <= 9;i++) {
for(int j = 1;j <= i;j++)//列数与行数相等 {
printf("%d ×%d = %d\t", j, i, (i * j)); } printf("\n"); } return 0; }
第5章 好戏在后面
第1节 程序的3种结构
| 3种结构 | 特点 |
|---|---|
| 顺序执行 | 一行一行顺序地从上向下执行每条语句 |
| 选择执行 | 根据条件来选择需要执行的语句 |
| 循环执行 | 当条件满足时反复执行一段语句直到不满足条件时退出 |
第2节 啰嗦一下
第一:
逻辑挑战7:判断质数很简单
4)完整代码
//#define _CRT_SECURE_NO_WARNINGS//在VS下需加入 #include<stdio.h> #include<stdlib.h> int main() {
int a, count; scanf("%d", &a); count = 0;//用来统计有几个约数 for(int i = 2;i <= (a-1);i++)//从2~a-1寻找a的约数 {
if(a % i == 0)//如果a被i整除 {
count++; printf("%d ", i);//打印出约数 } } printf("\n"); printf("a有%d个约数\n", count); if(count == 0)//从2~a-1均没有a的约数 {
printf("a为质数\n"); } else//2~a-1之间有a的约数 {
printf("a为合数\n"); } return 0; }
第3节 更快一点:break
作用:
- 提前结束当前循环
- break是用来提前终止for、while或者do-while循环的
代码:优化判断质数
#define _CRT_SECURE_NO_WARNINGS//在VS下需加入 #include<stdio.h> #include<stdlib.h> int main() {
int a, count; scanf("%d", &a); count = 0;//用来统计有几个约数 for (int i = 2; i <= (a - 1); i++)//从2~a-1寻找a的约数 {
if (a % i == 0)//如果i被a整除 {
count++; break; } } if (count == 0)//从2~a-1均没有a的约数 {
printf("%d为质数\n", a); } else//2~a-1之间有a的约数 {
printf("%d为合数\n", a); } return 0; }
第4节 continue
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 1)//i为奇数 {
continue;//为奇数则跳过之后的语句,提前进入下一次循环 } printf("%d ", i); } return 0; }
分析:
- i%2 == 1,表示i为奇数
- 当i为奇数时,跳过之后的打印语句,提前进入下一次循环
总结:
- break使循环提前跳出
- continue强迫程序提前进入下一轮循环
逻辑挑战8:验证哥德巴赫猜想
分析:
- 将每一个数k拆分为a+b的形式,且a的范围是2~k/2
- 判断a和b是否为质数
代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
for (int k = 4; k <= 100; k = k + 2)//4~100之间的偶数 {
for (int a = 2; a <= k / 2; a++)//找出其中一个质数 {
//判断a是否为质数 int count1 = 0; for (int i = 2; i <= a - 1; i++) {
if (a % i == 0)//i能被a整除,则a不是质数 {
count1++; break;//a在2~a-1之间有约数,a不是质数,提前结束当前循环,继续寻找下一个a } } if (count1 == 0)//如果a是质数 {
int b = k - a;//寻找另一个质数b //判断b是否为质数 int count2 = 0; for (int i = 2; i <= b - 1; i++) {
if (b % i == 0)//i能被b整除,则b不是质数 {
count2++; break;//b在2~b-1之间有约数,b不是质数,提前结束当前循环,继续寻找下一个a } } if (count2 == 0)//如果b也是质数 {
printf("%d = %d + %d\n", k, a, b);//a和b均为质数,打印出这个解 break;//打印这个解并跳出循环 //若想输出每一个偶数的所有可能的拆分方法,则注释掉break } } } } return 0; }
逻辑挑战9:水仙花数
//#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
for (int i = 1; i <= 9; i++)//百位1~9 {
for (int j = 0; j <= 9; j++)//十位0~9 {
for (int k = 0; k <= 9; k++)//个位0~9 {
if (i * 100 + j * 10 + k * 1 == i * i * i + j * j * j + k * k * k)//如果"个位数的立方 + 十位数的立方 + 百位数的立方"恰好等于这个数 {
printf("%d\n", i * 100 + j * 10 + k); } } } } return 0; }
拼接法”,即分别枚举百位、十位、个位上的数的所有可能,然后再拼接成一个3位数(百位×100+十位×10+个位)
- 如何将一个数拆分成三部分
- 获取一个数个位、百位、十位上的数
重点:
- 三位数获取个位上的数、十位上的数、百位上的数
//a,b,c分别为x百位、十位、个位上的数 a = x / 100 % 10;//让原来的百位变成个位再取个位 b = x / 10 % 10;//让原来的十位变成个位再取个位 c = x / 1 % 10;//取个位
代码:
//#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int x, a, b, c; for (x = 100; x <= 999; x++) {
a = x / 100 % 10;//百位数 b = x / 10 % 10;//十位数 c = x / 1 % 10;//个位数 if (x == a * a * a + b * b * b + c * c * c)//如果"个位数的立方 + 十位数的立方 + 百位数的立方"恰好等于这个数 {
printf("%d ", x); } } return 0; }
“分割法”,将一个三位数x拆分成3部分,即a、b、c,分别用来存放百位、十位、个位上的数。
逻辑挑战10:解决奥数难题
- 让变量i从1到9循环
- 每次循环只需判断一下当前的i是否符合这个等式的条件
- 如果符合就输出其值
代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
for (int i = 1; i <= 9; i++)//让变量i从1到9循环 {
if ((i * 10 + 3) * 6528 == (3 * 10 + i) * 8256)//如果符合等式 {
printf("%d\n", i); } } return 0; }
问题二:在上面的算式中,A、B、C、D、E分别代表5个互不相同的整数,请问A、B、C、D、E分别为多少时算是才会成立?请输出这个算式。
分析:
- ABCD×E = DCBA成立则输出
- ABCDE取值范围只可能是0~9
- 五个嵌套循环可以解决
代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
//遍历ABCDE五个数的所有组合 for (int a = 0; a <= 9; a++) {
for (int b = 0; b <= 9; b++) {
for (int c = 0; c <= 9; c++) {
for (int d = 0; d <= 9; d++) {
for (int e = 0; e <= 9; e++) {
if(a != b && a != c && a != d && a != e && b != c && b != d && b != e && c != d && c != e && d != e)//如果ABCDE互不相等 if ((a * 1000 + b * 100 + c * 10 + d) * e == (d * 1000 + c * 100 + b * 10 + a))//如果符合等式 {
//满足两个条件则按格式输出 printf("%d%d%d%d\n", a, b, c, d); printf("× %d\n", e); printf("——\n"); printf("%d%d%d%d\n", d, c, b, a); } } } } } } return 0; }
逻辑挑战11:猜数游戏
问题:
计算机会随机地给出0~99之间的一个整数,每猜一次,计算机都会告诉你猜大了还是小了,要求在限定的次数内猜出来。
获取随机数
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> int main() {
srand((unsigned)time(NULL));//初始化随机数种子,通过当前时间获得这个随机种子 int a = rand();//根据srand()提供的种子值,返回一个随机数 printf("%d", a); return 0; }
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> int main() {
int a, b, sum; sum = 6;//表示有6次猜的机会 srand((unsigned)time(NULL)); a = rand() % 100;//随机生成一个0~99之间的数 while (1) {
sum--;//开始猜数时,首先要消耗一次机会 scanf("%d", &b); if (b > a) printf("大了,还剩下%d次机会,请继续\n", sum); else if (b < a) printf("小了,还剩下%d次机会,请继续\n", sum); else//b == a {
printf("恭喜你,答对了!\n"); break; } if (sum == 0)//猜数机会用完 {
printf("已经没有机会了,请重新开始吧!\n"); break; } } return 0; }
逻辑挑战12:你好坏,关机啦
语法:
system("shutdown -s -t 50");
system("shutdown -a");
取消关机的命令。
第6章 天啊!一大串数正在接近
第1节 借用数组逆序输出
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a[5];//声明一个元素个数为5的数组 //输入0~4号元素到数组a中 for (int i = 0; i <= 4; i++) {
scanf("%d", &a[i]); } //逆序输出 for (int i = 4; i >= 0; i--) {
printf("%d ", a[i]); } return 0; }
逻辑挑战13:淘淘摘苹果
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
//输入10个苹果到地面的高度(100~200) int appleHigh[10];//声明一个长度为10的数组 printf("请分别输入10个苹果距离地面的高度:\n"); for (int i = 0; i < 10; i++) {
scanf("%d", &appleHigh[i]);//分别输入10个苹果距离地面的高度 } //输入陶陶把手伸直时能够达到的最大高度(100~120) int handHigh, bench = 30;//30cm高的板凳 printf("请输入陶陶把手伸直时能够达到的最大高度:\n"); scanf("%d", &handHigh); int cnt = 0;//用来记录陶陶所摘的苹果数量 for (int i = 0; i < 10; i++) {
if (appleHigh[i] <= (handHigh + bench)) cnt++; } printf("陶陶能够摘到的苹果的数目是:%d\n", cnt); return 0; }
逻辑挑战14:一个萝卜一个坑
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a[10], t;//先创建10个“小房间” //1、将10个小房间中的值初始化为0 for (int i = 0; i <= 9; i++) a[i] = 0; //2、将输入的数字对应小房间里的值改为1 for (int i = 1; i <= 5; i++) {
scanf("%d,", &t);//以此读入5个数 a[t] = 1;//把对应的小房间改为1 } //3、输出没有出现过的数 for (int i = 0; i <= 9; i++) {
if (a[i] == 0) printf("%d ", i); } return 0; }
核心:
- 出现过的数,它们所对应的小房间中的值都为1
- 没有出现过的数,所对应的小房间中的值都为0
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a[10], t;//先创建10个“小房间” //1、将10个小房间中的值初始化为0 for (int i = 0; i <= 9; i++) a[i] = 0; //2、将输入的数字对应小房间里的值增加1,用来统计该数出现的次数 for (int i = 1; i <= 5; i++)//循环读入5个数 {
scanf("%d,", &t);//把每一个数读到变量t中 a[t]++;//t所对应的小房间中的值增加1,以此作为出现次数 } //3、从小到大依照出现的次数输出对应的序号,从而实现将输入的数从小到大排序 for (int i = 0; i <= 9; i++)//依次判断0~9这10个小房子 {
for (int j = 1; j <= a[i]; j++)//出现了几次就打印几次 printf("%d ", i); } return 0; }
- 用a[i]来记录数字出现的次数
- 从小到大输出输入的数字,从而实现从小到大排序
逻辑挑战15:选择排序
完整排序过程:
| 初始数据 | [77 45 26 86 9] |
|---|---|
| 第1轮排序后 | 9 [77 45 86 26] |
| 第2轮排序后 | 9 26 [77 86 45] |
| 第3轮排序后 | 9 26 45 [86 77] |
| 第4轮排序后 | 9 26 45 77 [86] |
| 第5轮排序后 | 9 26 45 77 86 |
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a[1000];//创建一个长度为1000的数组 //1、输入要排序的数 int n; scanf("%d", &n);//输入n个数 for (int i = 0; i < n; i++) scanf("%d", &a[i]); //2、将5个数进行选择比较 for (int i = 0; i < (n-1); i++)//5个数只需比较4次 {
for (int j = i + 1; j <= (n-1); j++)//a[i]分别与a[i+1]、a[i+2]……a[5]比较 {
if (a[i] > a[j])//若前面的数比后面的数大,则交换两数位置 {
int temp = a[i]; a[i] = a[j]; a[j] = temp; } } } //3、输出排好序的数 for (int i = 0; i < n; i++) printf("%d ", a[i]); return 0; }
- a[i]依次与a[i+1]、a[i+2]……a[5]比较
第2节 二维数组
1、创建及打印二维数组
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a[3][4]; int x = 0; for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 3; j++) {
a[i][j] = x; x++; } } for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= 3; j++) {
printf("%d\t", a[i][j]); } printf("\n");//一行打印完毕需要换行 } return 0; }
int a[10] = {
0};
要点:
- 编译器会从a[0]开始按顺序赋值,后面没有具体值得将默认为0
- 只定义一个数组而不进行任何初始化,则每一个数组元素的默认值都将是随机值
二维数组的初始化:
int a[3][5] = {
{
1,2,3}, {
4,5}};
每一个括号代表一行。
第7章 有了它你能做更多的事
第1节 字符的妙用
简易计算器:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int a, b; char c; scanf("%d%c%d", &a, &c, &b); if (c == '+') printf("%d", a + b); if (c == '-') printf("%d", a - b); if (c == '*') printf("%d", a * b); if (c == '/') printf("%d", a / b); return 0; }
第2节 多余的回车键
getchar():
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
char a; a = getchar(); printf("你刚才输入的字符是:%c\n", a); return 0; }
getchar();与scanf(“%c”, &a);的作用是完全一样的。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include <conio.h> int main() {
char a; a = _getche(); printf("你刚才输入的字符是:%c\n", a); return 0; }
总结:
第3节 字符的本质
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
int i; for (int i = 0; i <= 127; i++) {
printf("%d %c\n", i, i); } return 0; }
计算机本质上只能存储0和1,任意整数都可以通过进制转换的方式变化成0和1的序列。所以表示字符最简单的方法就是把字符用整数来代替。字符所对应的整数就是该字符的ASCII码。
第4节 人名怎么存储呢
如何读取一行字符串:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
char a[10]; scanf("%s", a); printf("%s", a); return 0; }
此处的字符数组a(或者称作字符串a)只申请了10个空间,但只能存9个有效字符,因为最后一个需要用来存储字符串的结束标记‘\0’。
注意,a前面没有取址符“&”。(只有与“%s”配合使用来读取一行字符串时,才不需要在变量前加取址符“&”。)
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
char a[101], b[101]; int x, y; scanf("%s", a); scanf("%d", &x); scanf("%s", b); scanf("%d", &y); if (x > y) printf("%s", a); else {
if (x < y) printf("%s", b); else printf("%s和%s的分数相同", a, b); } return 0; }
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
char a[10]; scanf("%s", a); printf("%s", a); return 0; }
代码2:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() {
char a[10]; gets_s(a); printf("%s", a); return 0; }
由此可见,用scanf进行字符串读入时,遇到空格就提前终止了,但是用gets进行读入时却可以读入一整行。
注意: VS2019使用的是新C标准,也就是C11,而VC6.0用的是老标准。 在新标准中,应该是用gets_s代替gets。
输出字符puts:
puts(a);
使用puts(a)输出时,会在末尾自动换到下一行,相当于printf(“%s\n”, a)。
字符数组赋初始值:
char a[10] = {
"hello"};
在字符串的两边加上双引号和花括号就可以了。
逻辑挑战16:字母的排序
完整代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//用strlen()函数的头文件 int main() {
char a[101];//假设读入的字符不超过100个 int len;//存储字符串长度的整型变量 gets_s(a);//输入字符串 len = strlen(a);//通过strlen()函数获取字符串a的长度 for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j <= len - 1; j++) {
if (a[i] > a[j]) {
char t = a[i]; a[i] = a[j]; a[j] = t; } } } puts(a);//输出排完序的字符串 return 0; }
逻辑挑战17:字典序
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//用strcmp函数需此头文件 int main() {
char a[101], b[101]; gets_s(a); gets_s(b); if (strcmp(a, b) <= 0)//a在b前面或a和b是同一个字符串 {
puts(a); puts(b); } else//a在b后面 {
puts(b); puts(a); } return 0; }
第7节 多行字符
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//用strcpy()、strcmp()函数必须包含 int main() {
char a[5][11]; //输入5行字符串 for (int i = 0; i <= 4; i++) {
gets_s(a[i]); } //输出5行字符串 for (int i = 0; i <= 4; i++) {
puts(a[i]); } return 0; }
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//用strcpy()、strcmp()函数必须包含 int main() {
char a[5][11], t[11]; //输入字符串(0~4行) for (int i = 0; i <= 4; i++) {
gets_s(a[i]); } //选择排序 for (int i = 0; i <= 3; i++) {
for (int j = i + 1; j <= 4; j++) {
if (strcmp(a[i], a[j]) > 0)//如果按字典顺序字符串a[i]在a[j]的后面 {
//互换顺序 strcpy(t, a[i]); strcpy(a[i], a[j]); strcpy(a[j], t); } } } //输出排序后的字符串(0~4行) for (int i = 0; i <= 4; i++) {
puts(a[i]); } return 0; }
- 字符串比较函数strcmp()
- 字符串复制函数strcpy()
- 头文件#include<string.h>
第8节 存储一个迷宫
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h>//用strcpy()、strcmp()函数必须包含 int main() {
char maze[7][12] = {
"", "#O # ", "# #", "# # # #", "# #", "# # ", "" }; //循环输出第0行到第6行 for (int i = 0; i <= 6; i++) puts(maze[i]); return 0; }
第8章 游戏时间到了
第1节 走迷宫
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include <conio.h>//用_getche()函数需包含 int main() {
system("color f5");//变色 //定义迷宫 char a[50][50] = {
"", "#O # # ", "# # # # # # ", "# # # # # ", "# # # # ", " # # ", "# # # # # # # #", "# # # # # # ", "# # # # # ", "# # # # ", "# # # #", "# # # # #", "# # # # ", "# # # # #", "# # ", " # # # # #", "# # # #", "# # #", "# # # #", "" }; //定义小球初始位置和迷宫的出口 int x, y, p, q; x = 1; y = 1; p = 12; q = 29;//x和y来存储小球的初始位置,p和q来存储迷宫的出口 //输出迷宫 for (int i = 0; i <= 19; i++) puts(a[i]); //定义上下左右按键 while (x != p || y != q) {
//S:向下移动 char ch = _getche(); if (ch == 's') {
if (a[x + 1][y] != '#')//只有下一步不是栅栏“#”时小球才能移动 {
a[x][y] = ' ';//让小球当前位置变为空格 x++;//更改小球的位置 a[x][y] = 'O';//将小球新位置上的内容替换为小球“O” } } //W:向上移动 if (ch == 'w') {
if (a[x - 1][y] != '#') {
a[x][y] = ' '; x--; a[x][y] = 'O'; } } //A:向左移动 if (ch == 'a') {
if (a[x][y - 1] != '#') {
a[x][y] = ' '; y--; a[x][y] = 'O'; } } //D:向右移动 if (ch == 'd') {
if (a[x][y + 1] != '#') {
a[x][y] = ' '; y++; a[x][y] = '0'; } } //清屏并输出新迷宫的状态 system("cls"); for (int i = 0; i <= 19; i++) puts(a[i]); } system("cls"); printf("恭喜你成功走出迷宫了!\n"); Sleep(5000); return 0; }
第2节 推箱子
分析:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include <conio.h>//用_getche()函数需包含 int main() {
//提示文字 system("color f5");//变色 printf("请通过WSAD(小写模式)键控制小人‘S’移动\n"); //按任意键清屏 system("pause"); system("cls"); //定义推箱子地图 char sokoban[50][50] = {
"", " ", "O #", "# S O O #", "# # O ", " ", "" }; //定义推箱人初始位置和箱子的位置 int x = 3, y = 2, p1 = 4, q1 = 2, p2 = 4, q2 = 3, p3 = 5, q3 = 2, p4 = 5, q4 = 3; //输出推箱子地图 for (int i = 0; i <= 8; i++) puts(sokoban[i]); while (sokoban[p1][q1] != '@' || sokoban[p2][q2] != '@' || sokoban[p3][q3] != '@' || sokoban[p4][q4] != '@') {
if (sokoban[p1][q1] == 'O') sokoban[p1][q1] = '@'; if (sokoban[p2][q2] == 'O') sokoban[p2][q2] = '@'; if (sokoban[p3][q3] == 'O') sokoban[p3][q3] = '@'; if (sokoban[p4][q4] == 'O') sokoban[p4][q4] = '@'; //定义上下左右按键 char ch = _getche(); //W if (ch == 'w') {
if (sokoban[x + 1][y] == '@' && sokoban[x+2][y] == '#' || sokoban[x][y + 1] == '@' && sokoban[x][y + 2] == '#' || sokoban[x + 1][y + 1] == '@' && sokoban[x + 1][y + 2] == '#' && sokoban[x][y + 2] == '#') {
sokoban[x][y] = '*'; x--; sokoban[x][y] = 'S'; } else if (sokoban[x - 1][y] != 'O' && sokoban[x - 1][y] != '@') {
if (sokoban[x - 1][y] != '#') {
sokoban[x][y] = ' '; x--; sokoban[x][y] = 'S'; } } else {
if (sokoban[x - 2][y] != '#' && sokoban[x - 2][y] != '@')//箱子的左边 {
sokoban[x][y] = ' ';//原来位置是空格 x--; sokoban[x][y] = 'S';//新位置是S sokoban[x - 1][y] = 'O';//新箱子位置 } } } //S if (ch == 's') {
if (sokoban[x + 1][y] != 'O' && sokoban[x + 1][y] != '@') {
if (sokoban[x + 1][y] != '#') {
sokoban[x][y] = ' '; x++; sokoban[x][y] = 'S'; } } else {
if (sokoban[x + 2][y] != '#' && sokoban[x + 2][y] != '@')//箱子的左边 {
sokoban[x][y] = ' ';//原来位置是空格 x++; sokoban[x][y] = 'S';//新位置是S sokoban[x + 1][y] = 'O';//新箱子位置 } } } //A if (ch == 'a') {
if (sokoban[x][y + 1] == '@' && sokoban[x][y + 2] == '#' || sokoban[x + 1][y] == '@' && sokoban[x + 2][y] == '#') {
sokoban[x][y] = '*'; y--; sokoban[x][y] = 'S'; } else if (sokoban[x][y - 1] != 'O' && sokoban[x][y - 1] != '@') {
if (sokoban[x][y - 1] != '#') {
sokoban[x][y] = ' '; y--; sokoban[x][y] = 'S'; } } else {
if (sokoban[x][y - 2] != '#' && sokoban[x][y - 1] != '@')//箱子的左边 {
sokoban[x][y] = ' ';//原来位置是空格 y--; sokoban[x][y] = 'S';//新位置是S sokoban[x][y - 1] = 'O';//新箱子位置 } } } //D if (ch == 'd') {
if (sokoban[x][y + 1] != 'O' && sokoban[x][y + 1] != '@') {
if (sokoban[x][y + 1] != '#') {
sokoban[x][y] = ' '; y++; sokoban[x][y] = 'S'; } } else {
if (sokoban[x][y + 2] != '#' && sokoban[x][y + 2] != '@')//箱子的左边 {
sokoban[x][y] = ' ';//原来位置是空格 y++; sokoban[x][y] = 'S';//新位置是S sokoban[x][y + 1] = 'O';//新箱子位置 } } } //清屏并输出 system("cls"); for (int i = 0; i <= 8; i++) puts(sokoban[i]); } Sleep(1000);//等待1s //提示成功 system("cls"); printf("恭喜你成功通关!\n"); return 0; }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/111013.html