分支语句
一.if语句
1.单分支语句
(1)表达式:表达式是决定选择方向的条件,当表达式结果为真时执行下面的语句,为假时进入其他位置执行下面的语句。
(2)C语言对真假的判断:在C语言中,0表示假,非零表示真。
(3)语句:表示上面表达式为真时所执行的代码。
(4)注意加上空格以保证代码的可读性。
if(表达式)
语句;
#include<stdio.h>
int main()
{
int year = 0;
scanf("%d", &year);
if (year < 18)
printf("未成年\n");
printf("不能饮酒\n");
return 0;
}
(5)当需要执行的语句多于一条时,注意要加上代码块——{}。
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("未成年\n");
printf("不能饮酒\n");
}
return 0;
}
`
2.双分支语句
if(表达式)
语句;
else
语句;
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("未成年\n");
}
else
{
printf("成年\n");
}
return 0;
}
3.多分支语句
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
(6)添加更多的分支时使用else if ()语句
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("青少年\n");
}
else if(age>=18&&age<28)
{
printf("青年\n");
}
else if (age >= 28 && age < 40)
{
printf("中年\n");
}
else if (age >= 40 && age < 60)
{
printf("壮年\n");
}
else
{
printf("老年");
}
return 0;
}
在多分支语句中判断表达式(age >= 28 && age < 40)但是不能用28<=age<=40
。拿80来举例子,28<=age正确为1,1<=40正确,那么会输出中年但实际是老年。
4.if语句常见易错点及良好的代码规范
请看以下代码:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)//a不等于1
if(b == 2)
printf("hehe\n");
else//这个else会对应离他最近的if,也就是if(b == 2)
printf("haha\n");
return 0;
}
如果后面不加注释,则有些人就可能会认为这个if…else语句的else对应的是if(a==1)的那个if 可实际上输出的却是无打印
所以我们尽量要添加{}对分支语句进行优化
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
{
printf("hehe\n");
}
else
{
printf("haha\n");
}
}
return 0;
}
//输出还是不打印
如果想打印出haha 改正后
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
{
printf("hehe\n");
}
}
else
{
printf("haha\n");
}
return 0;
}
//输出:打印haha
(1)else语句会对应离它最近的那个if语句
(2)选择语句if在使用时,如果我们对else的范围没有操作,else可以省去
(3)对于优化代码 不管是一条还是多条语句都加上{},这样保证了代码的可读性。
下面来给大家再来看一个不规范的代码
//代码1
if (condition)
{
return x;
}
return y;
//代码2
if(condition)
{
return x;
}
else
{
return y;
}
//这两段代码的实际作用是一样的,当表达式的值为真时返回x,否则返回y(只要返回就不会执行了)
//但是相比而言,第二个代码的表达更加清晰,多写一个else也并不费力
我们再写代码的初期常会遇到一个问题,我们经常会把‘==’符号写作‘=’
#include<stdio.h>
int main()
{
int a = 0;
if (a = 1)//这个表达式表示把1赋值给a,表达式的值为1,为真,打印hehe
{
printf("hehe\n");
}
if (a = 0)//这个表达式表示把0赋值给a,表达式的值为0,为假,不打印haha
{
printf("haha\n");
}
return 0;
}
//只要一个等于号符的值不为0,程序就可以正常运行
为了规避这种错误,我们可以这样
//代码3
int num = 1;
if(num == 5) //只是单纯判断num是不是等于5,少写一个等于号依旧正常运行
{
printf("hehe\n");
}
//代码4
int num = 1;
if(5 == num)
//有判断作用,但少写一个等于号时(5 = num)
//5是一个常量,而num是一个变量,变量的值不能赋给常量,编译器报错
{
printf("hehe\n");
}
if (num % 2 == 1)//表达式不需要颠倒,因为表达式本来就不能赋值
{
printf("hehe\n");
}
代码4是老司机的写法,极力推荐这种写法——当我们需要的条件是判断一个变量是否等于某个常量时,通过将变量和常量颠倒的方法就有效避免了这样的低级错误。表达式不需要颠倒。(只适用于判断a == 1这样的条件)
5.例题
(1)判断一个数是否为奇数
#include<stdio.h>
int main()
{
int num = 0;
scanf("%d",num);
if (num % 2)
{
printf("是奇数\n");
}
else
{
printf("不是奇数\n");
}
return 0;
}
(2)输出1-100之间的奇数
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 100; i++)//或者把i++直接改成i+=2
{
if (i % 2 == 1)
{
printf("%d ", i);
}
}
return 0;
}
二.switch语句
1.基本使用方法
switch语句常常用于多分支的情况。
比如:
输入1,输出星期一
输入2,输出星期二
输入3,输出星期三
输入4,输出星期四
输入5,输出星期五
输入6,输出星期六
输入7,输出星期日
我们使用if语句就太麻烦了,而switch语句更适合这样的程序。
switch的用法如下:
switch(整型或字符型表达式)
{
case 整型或字符型常量表达式:
语句;
case 整型或字符型常量表达式:
语句;
case 整型或字符型常量表达式:
语句;
......
}
2.case与break语句在switch语句中的应用
(1)在switch语句中,case语句只表示程序的入口,当输入的值符合case后的常量表达式时,程序会进入这个入口,从上向下执行。加上break就可以跳出switch语句以达到分支的目的。
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:printf("星期一\n");
break;
case 2:printf("星期二\n");
break;
case 3:printf("星期三\n");
break;
case 4:printf("星期四\n");
break;
case 5:printf("星期五\n");
break;
case 6:printf("星期六\n");
break;
case 7:printf("星期日\n");
break;
}
return 0;
}
(2)switch语句中几个常量表达式也可以对应一条语句
比如:
输入1-5,输出工作日
输入6或7,输出休息日
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:printf("weekdey\n");
break;
case 6:
case 7:printf("weekend\n");
break;
}
return 0;
}
#include <stdio.h>
int main ()
{
/* 局部变量定义 */
char grade = 'B';
switch(grade)
{
case 'A' :
printf("很棒!\n" );
break;
case 'B' :
case 'C' :
printf("做得好\n" );
break;
case 'D' :
printf("您通过了\n" );
break;
case 'F' :
printf("最好再试一下\n" );
break;
default :
printf("无效的成绩\n" );
}
printf("您的成绩是 %c\n", grade );
return 0;
}
切记:字符型变量用于switch语句的时候记得打单引号
3.default语句
当表达式的值与每一个case语句都不匹配时,你也想执行一些代码处理数据时,就可以加上default语句(类似于if…else语句中的else)
(1)每个switch语句中只能出现一条default子句。
(2)default语句可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:printf("weekdey\n");
break;
case 6:
case 7:printf("weekend\n");
break;
default:printf("输入数据错误\n");
}
return 0;
}
4.例题
请问下面程序输出结果(switch允许嵌套使用)
#include <stdio.h>
int main()
{
int n = 1;
int m = 2;
switch (n)//此时n为1
{
case 1:m++;//进入,m变为3
case 2:n++;//继续,n在case 2中递增,所以n在case 3中直接进入case 2
case 3:
switch (n)
{
case 1: n++;
case 2: m++; n++;
break;
}
case 4:
m++;
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
return 0;
}
结果是 m=5, n=3
循环语句
一、while循环
1.基本使用方法
while(表达式)
循环语句;
括号中的表达式是判断循环是否进行的依据。
表达式结果为真时,循环继续进行;为假时,跳出循环。
打印1-10的数字
#include<stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
i++;
printf("%d ", i);
}
return 0;
}
2.while循环中break与continue的使用方法
(1)break
在循环中只要遇到break,就停止后期的所有操作,直接终止循环。而如果存在嵌套循环,只跳出它所在的那个循环。
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (5 == i)
break;
printf("%d ", i);
i++;
}
return 0;
}
(2)continue
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
i +=1;//先将i加1
if(i == 5)//循环3次后,第4次进入循环时,满足条件
continue;//跳过下面的语句并继续循环,就不会打印5
printf("%d ", i);
}
return 0;
}
//输出:2 3 4 6 7 8 9 10 11
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
if(i == 5)//循环4次后,第5次进入循环时,满足条件
continue;//跳过下面的语句并继续循环
//跳过i+=1;语句后,i=5的值不会被改变,这就变成了一个死循环
printf("%d ", i);
i++;
}
return 0;
}
//输出:1 2 3 4 死循环
3.例题
(1)输入一个字符并打印它
getchar()与putchar()函数
getchar()函数:从内存缓冲区中找到并拿走输入的一个字符
当你没有输入字符时,getchar函数会先等待输入,当内存缓冲区
putchar()函数:打印一个字符
1.内存缓冲区
我们前面提到getchar函数时从内存缓冲区中拿出一个字符,那这个内存缓冲区又是什么呢?
缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。
也就是说,输入的内容不会直接进入内存(键盘)中而是先进入内存缓冲区,再进入内存。
2.什么是EOF
EOF表示end of file(文件结束标志),在计算机中它的定义是-1
#include <stdio.h>
int main()
{
int ch = 0;
//定义一个字符,因为字符在计算机中储存为ASCII码值,所以可以定义为整形
while ((ch = getchar()) != EOF)//当取到输入字符为EOF时,跳出循环
putchar(ch);//putchar用于打印单个字符,打印ch
return 0;
}
//getchar()函数可以在内存缓冲区中读取到一个输入字符
//(ch = getchar())表示把getchar()得到的字符赋给ch这个函数的返回值,
//它的返回值应该是字符ch对应的ASCII码值
//(ch = getchar()) != EOF 表示函数返回值不是EOF
//注意:我们想向下运行程序需要按回车,
//回车输入的\n也是一个字符,相当于程序运行了两遍
//getchar先读取到你输入的字符,比如字母a,然后缓冲区中还有一个输入的\n
//相当于getchar先找到你输入的字符进行打印,然后又找到了\n,进行打印
//(即读完字符后又读了回车\n)
//这个while语句实现了多次输入,
//而当我们想结束程序跳出循环时,只需要按ctrl+z就会使函数读取到EOF
//输入:a
//输出:a
//
(2)写一个输入密码的程序
#include<stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);
printf("请确认密码(Y/N):");
int ch = getchar();
if(ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
//这个代码的问题是:当你输出abcdef的时候,直接就确认失败了,
//scanf需要读取数据,键盘上直接输入abcdef(还敲了一个回车),
//scanf并不是直接从键盘中拿取数据的,在scanf与键盘之间还存在一个输入缓冲区.
//scanf的工作原理是:先去输入缓冲区看一眼,有东西就读,没东西就等着输入.
//实际上abcdef\n一开始输入的时候先放至缓冲区,
//这个时候scanf看到缓冲区有东西了,它就去拿走了abcdef放到password里面去了,
//这个时候getchar读数据时发现缓冲区有\n
//(如果getchar发现缓冲区里面是空的,那么它将等待输入Y/N),
//于是把它读走放到ch上了,\n!='Y',因此确认失败。
那么我们怎么修改呢?
#include<stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码:>");
scanf("%s", password);
//清理\n,方法1:
getchar();//这个还不是最完美的方法,因为scanf读取字符串的时候遇到空格以后就不会再读了(输入:abcedf haha,password只读走了前面的abcdef,而 haha\n(空格haha\n)留在了缓冲区内,可getchar只能读一个字符.)
//方法2:
int temp = 0;
while((temp = getchar()) != '\n')//temp先接受一个字符,如果它不等于'\n',它就继续读,直到读到\n,\n!=\n为假,因此清理掉了\之前的所有字符。
{
;
}
printf("请确认密码(Y/N):");
int ch = getchar();
if(ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
(3)打印字符串中的数字字符
//代码2
#include <stdio.h>
int main()
{
int ch = '\0';//对ch进行初始化,而'\0'的ASCII码为0 用char定义不严谨,因为getchar是由int而来,char的话可能会引发截断现象.
while ((ch = getchar()) != EOF)//一个一个读取
{
if (ch < '0' || ch > '9')//相当于把它们的ASCII码值进行比较
continue;//ch为非数字字符进入,跳过putchar
putchar(ch);//为数字字符,不进入if,打印
}
return 0;
}
//输入:abc1dcwrew123
//输出:1123
二、for循环
1.基本使用方法
for(表达式1; 表达式2; 表达式3)
循环语句;
其中,
表达式1负责初始化,用于初始化循环变量;
表达式2负责判断,用于判断循环时候终止;
表达式3负责调整,用于循环条件的调整。
#include<stdio.h>
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
//这里的i被初始化为0,这个省去对程序运行也没有影响,
//但为了避免出错还是应当加上
{
printf("%d ",i);//当i的值满足i<=10时打印i
//在程序内的语句块执行完成后,程序执行调整语句i++,
//然后再次判断是否满足循环条件
}
return 0;
}
//输出:1 2 3 4 5 6 7 8 9 10
这种情况while与for循环 我选择后者
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
if(i == 5)//循环4次后,第5次进入循环时,满足条件
continue;//跳过下面的语句并继续循环
//跳过i+=1;语句后,i=5的值不会被改变,这就变成了一个死循环
printf("%d ", i);
i +=1;
}
return 0;
}
//输出:1 2 3 4 死循环
改成for循环后
#include <stdio.h>
int main()
{
int i = 1;
for (i=1; i<=10; i++)
{
if(i == 5)//循环4次后,第5次进入循环时,满足条件
continue;
//跳过下面的语句进行调整后继续循环,
//i不会保持在5的数值上
printf("%d ", i);
}
return 0;
}
//输出:1 2 3 4 6 7 8 9 10
2.for循环中break与continue的使用方法
与while相同
3.for循环的一些注意事项和特殊代码
(1)不要在语句块内部改变循环变量以防循环失去控制
#include<stdio.h>
int main()
{
int i = 0;
for(i = 1;i <= 10;i++)
{
printf("%d ", i);
i = 5;
}
return 0;
}
//6 死循环 初始化i=1改成了5,然后i++
(2)特殊for循环写法
#include <stdio.h>
int main()
{
//代码1
for(;;)
{
printf("hehe\n");
}
//for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议省略。
//代码2
int i = 0;
int j = 0;
//根据for循环的嵌套,这里会打印100个hehe
for(i = 0; i < 10; i++)
{
for(j = 0; j < 10; j++)
{
printf("hehe\n");
}
}
//代码3
int i = 0;
int j = 0;
//如果省略掉初始化部分,这里只打印10个hehe
for(; i < 10; i++)
{
for(; j < 10; j++)
{
printf("hehe\n");
}
}
//在第一次进入循环时程序正常工作j=10时跳出循环,
//没有初始化变量j就会一直保持10,
//从此不会再次进入循环,
//i从1变到10的过程中只是孤零零地重复了9次,没有操作
//代码4,可以使用多个变量控制循环
int x, y;
for (x = 0, y = 0; x < 2 && y < 5; ++x, y++)
{
printf("hehe\n");
}
return 0;
}
4.例题
//请问循环要循环多少次?
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i = 0,k = 0; k = 0; i++,k++)
k++;
return 0;
}
//答案:零次,在for循环的判断那里k=0的表达式值本来就为0,0为假,不循环
三、do…while循环
1.基本使用方法
do
循环语句;
while(表达式);
它不管条件符不符合它就先执行,执行完在判断是否需要继续再执行一遍。
特点:循环至少执行一次。
#include <stdio.h>
//用do...while循环打印1~10
int main()
{
int i = 1;
do//先执行
{
printf("%d\n", i);
i++;
} while (i < 10);//判断能不能接着执行,若不能,则跳出
return 0;
}
//输出:1 2 3 4 5 6 7 8 9 10
2.do…while循环中break与continue的使用方法
与while、for循环相同
#include <stdio.h>
//用do...while循环打印1~10
int main()
{
int i = 1;
do//先执行
{
if(5 == i)
continue;
printf("%d\n", i);
i++;
} while (i <= 10);//判断能不能接着执行,若不能,则跳出
return 0;
}
//1 2 3 4 死循环,continue跳过了下面的printf和i++
如果想把除了5以外的1~10打印出来,则
#include <stdio.h>
//用do...while循环打印1~10(除了5)
int main()
{
int i = 0;
do//先执行
{
i++;
if(5 == i)
continue;
printf("%d\n", i);
} while (i < 10);//判断能不能接着执行,若不能,则跳出
return 0;
}
四、goto语句
#include<stdio.h>
int main()
{
again:
printf("hello ");
printf("world!\n");
goto again;
return 0;
}
这个程序的输出结果是一个死循环,用while循环语句也可以完成。
goto语句不能跨函数使用
1.基本使用方法
终止程序在某些深度嵌套的结构的处理过程。
例如:一次跳出两层或多层循环。goto语句适合使用。
for(...)
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
…
error:
if(disaster)
// 处理错误情况
再例如
#include<stdio.h>
int main()
{
flag:
printf("hehe\n");
goto flag;//打印完hehe后又跳回flag循环
return 0;
}
//死循环,无限个hehe
#include<stdio.h>
int main()
{
printf("hehe\n");
goto flag;
printf("haha\n");//跳过了haha
flag:
printf("heihei\n");
return 0;
}
//hehe (换行)heihei
用break语句只能跳出一层循环,而goto就可以一次跳出。
不过这东西是有名的bug来源之一,一般不建议写goto语句
goto语句与关机程序
下面是使用goto语句的一个例子,然后使用循环的实现方式替换goto语句:
电脑运行起来后,1分中内关机
如果输入:我是猪,就取消关机
对计算机命令关机:
shutdown -s -t 60 前面的英文是命令关机60是60s后
shutdown -a是停止关机
上面的这些命令通过system函数实现,头文件stdlib.h
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("请注意,你的电脑在60秒内关机,如果输入:我是猪,就取消关机\n");
scanf("%s", input);
if (strcmp(input, "我是猪")==0)
{
system("shutdown -a");
}
else
{
goto again;//如果他不承认他是猪,
//利用goto语句,跳到again:上再重新printf,scanf....
}
return 0;
}
利用while循环来写
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
char input[20] = { 0 };
system("shutdown -s -t 60");
while (1)
{
printf("请注意,你的电脑在60秒内关机,如果输入:我错了,就取消关机\n");
scanf("%s", input);
if (strcmp(input, "我错了") == 0)
{
system("shutdown -a");
break;
}
}
return 0;
}
五:循环的练习题
1.计算n的阶乘
#include<stdio.h>
int main()
{
int i = 1;
int ret = 1;
int num = 0;
scanf("%d", &num);
for (i = 1; i <= num; i++)
{
ret *= i;
}
printf("%d\n", ret);
return 0;
}
2.计算 1!+2!+3!+……+10!
#include<stdio.h>
int main()
{
int i = 1;
int ret = 1;
int sum = 0;
//n!=(n-1)!*n
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
ret *= i;
sum += ret;
}
printf("%d\n", sum);
return 0;
}
3.在有序数组中查找某个数字n(重要的算法思想)
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//二分查找/折半查找
int left = 0;
int sz = sizeof(arr) / sizeof(arr[0]);//sz为数组中的元素个数
int right = sz - 1;
int k = 0;//初始化要查找的数k
scanf("%d", &k);
while (left <= right)
{
//每次折半查找后left和right都会变,逐渐缩小范围
int mid = left + (right - left) / 2;//这种方法更严谨,可以检索更大范围的数组
if (arr[mid] < k)
{
left = mid + 1;
//1~10中折半查找得到mid是5,5的数组下标是4,
//如果要找的数k大于mid的下标,
//则继续折半查找,6即为新的left,下标为mid+1
}
else if (arr[mid] > k)
{
right = mid - 1;//同上,4为新的right,下标为mid-1
}
else
{
printf("找到了,下标是%d\n", mid);
break;//找到元素后退出循环
}
}
if (left > right)
{
printf("找不到\n");
}
return 0;
}
4.编写代码,演示多个字符从两端移动,向中间汇聚
//要达到这样的效果
//"welcome to bit!!!!!"
//"###################"
//"w#################!"
//"we###############!!"
//"wel#############!!!"
//...
//"welcome to bit!!!!!"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>//system函数的头文件
int main()
{
char arr1[] = { "welcome to bit!!!!!" };
char arr2[] = { "###################" };
//也要像二分查找一样定义left和right
int left = 0;
int right = strlen(arr1) - 1;//字符串长度-1就是最后一个元素的下标
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
sleep(1000);
//这个过程太快,可以利用sleep休眠函数将其慢下来,单位为毫秒
system("cls");
//如果想在同一行内变化,则可以利用cls—windows自带命令—清理屏幕
left++;//依次替代字符串中的元素
right--;
}
printf("%s\n", arr2);
//再打印防止字符串被同行数给消灭,导致打印出空的结果
return 0;
}
5.编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序。
//假设正确密码是"bitbit"
#include<stdio.h>
#include<string.h>
int main()
{
int i = 0;
char password[] = { 0 };
for (i = 0; i < 3; i++)
{
printf("请输入密码:>");
scanf("%s", password);
//字符串比较大小要利用strcmp函数,
//如果字符串中字符个数相同,
//则挨个字符ASCII码值比较,直到出现不同的字符或遇到\0为止,
//如果字符个数不相同(比如"abc","abcd"),
//就直接0与d比较,
//("b"与"abcd"),就直接b与a比较即可
//字符串如果左边大于右边,则返回值大于0,
//右边大于左边,则返回值为负整数,若相同,则返回值0
if (strcmp(password, "bitbit") == 0)
{
printf("密码正确,登录成功");
break;
}
else
{
printf("密码输入错误\n");
}
}
if (i == 3)
{
printf("三次密码输入错误,退出程序\n");
}
return 0;
}
6.猜数字游戏
//猜数字游戏
//随机生成1~100之间的数字
//如果你猜小了,告知猜小了
//如果你猜大了,告知猜大了
//如果你猜对了,告知猜对了
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
void menu()//打印起始页面的函数
{
printf("*********************************\n");
printf("********** 1. play ************\n");
printf("********** 0. exit ************\n");
printf("*********************************\n");
}
void game()//玩游戏的函数
{
int guess = 0;
//1.生成随机数
int ret = 0;
//rand函数可以生成一个随机数,
//这个数字的范围是0~RAND_MAX(32767),但想调用rand需要先调用srand函数
//而题目要求我们随机生成1~100之间的数字,所以:
ret = rand() % 100 + 1;//0~99=>1~100
//让我们去看下面的srand函数,在main函数下面
//看完srand函数后,此时rand函数可以正常生成一个随机值了
//srand只需要确定一次起始位置即可,所以没有把它放在生成熟知的函数里
printf("%d\n", ret);
//2.猜数字
while (1)//死循环直到猜中跳出
{
printf("请输入数字:");
scanf("%d", &guess);
if (guess > ret)
{
printf("猜大了\n");
}
else if (guess < ret)
{
printf("猜小了\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
}
int main()
{
//设置随机数的生成器
srand((unsigned int)time(NULL));//只需要生成1次即可
//调用srand函数确定一个生成随机数的起始位置
//(srand函数里面有个变化值即可,因为括号里随机输入一个数,结果都不一样)
//srand函数需要一个unsigned int类型的变动的值。
//我们要产生一个随机值,而这个随机值的生成需要一个随机值
//我们似乎进入了一个先有鸡先有蛋的问题,这时就需要引入一个概念叫做时间戳
//时间戳表示一个时间,
//这个时间就是相对于1970年1月1日到现在的时刻我们经过了多少秒,然后将它转化为一个数字,
//其实这个数字指的是:
//电脑此时此刻运行这个代码的时间和计算机的起始时间的一个差值,
//单位为s,就是一个时间戳
//由于时间是不断变动的,它就可以满足我们的要求,
//time函数可以实现当前的这个时间戳,可以返回这个数字,
//time函数需要一个指针类型的参数,
//如果不想要那个参数,那我们就给它一个空指针.
//它的返回类型是time_t,需要强制类型转换为unsigned int
//让我们回到rand函数那里
int input = 0;
do //do...while循环使得游戏至少执行一次
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
//生成随机数需要用rand函数来实现,但实际上它不够随机。
//所以我们设置了随机数生成器—srand函数,
//而srand()括号里面需要一个整数,这个整数需要时刻变化.
//所以我们给了一个时间戳,
//只要时间在变化,时间戳也在变化,所以我们调用time函数
//而在调用time函数的时候,发现我们不想用它的参数,
//所以我们传递空指针,而time函数返回的是time_t类型
//而time_t类型的值我们需要传递给srand函数,
//而srand函数需要的是unsigned int类型的值。
//所以我们把time函数的返回类型强制转换成了unsigned int类型,
//然后就可以生成随机数了