目录
一.分支语句
1.if语句
作为c语言最常见的判断语句,几乎有关判断的场景都要用到if来实现
1.1语法:
单分支:
if(表达式)
语句;
if(表达式)
语句1;
else
语句2;
多分支:
if(表达式1)
语句1;
else if(表达式2)
语句2;
else
语句3;
用if表达式中,表达式为真(非0)执行,为假(0)就停止执行。
1.2悬空else问题
#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,发现什么都没有打印,为什么?
因为:else与它最近的if匹配,第一个if判断为假,跳过下面的语句直接到return 0(第二个if与else可以说是捆绑在一起)
修改:
#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;
}
适当的使用{}可以使代码的逻辑更加清楚,写代码风格很重要!!
2.switch语句
swich语句常用于多分支的情况,比如要输出今天是星期几,如果用if来写,一堆的else if不方便,这时swich就派上用场了
2.1语法
switch(整型表达式)
{
语句项;
}
语句项由多个case组成,在case语句结束时通常要在末尾处加break表示此处分支结束
用switch语句写出今天的日期
#include <stdio.h>
int main()
{
int day = 0;
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;
}
但有时多个分支的需求时一样的,如想要知道今天时周末还是工作日
#include <stdio.h>
//switch代码演示
int main()
{
int day = 0;
switch(day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday\n");
break;
case 6:
case 7:
printf("weekend\n");
break;
}
return 0;
}
2.2default子句
如果表达的值与所有的case标签的值都不匹配怎么办? 其实也没什么,结构就是所有的语句都被跳过而已。 程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。 但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?
你可以在语句列表中增加一条default子句,case都不匹配时就跳到default子句执行,使得switch更加完整
补充:case与default子句在switch里的顺序没有固定(也就是说,它们可以出现在任何位置。)
二.循环语句
1.while循环
在生活中,如果一件事情要做多次,光用if行不通,C语言给我们提供了while语句
1.1语法
while(表达式)
{
循环语句;
}
whle循环流程图:
1.2break与continue
break作用:与swich类似,它通常是在while中当某种条件达到时,跳出while循环。所以,while中的break是用于永久终止循环的
continue作用:它的翻译是:继续。但别被它的翻译带乱了,它是在程序执行到它时跳过在while中continue下面的语句,在进行循环。(慎用,容易使得while死循环!!)
2.for循环
我们已经知道了while循环,但是我们为什么还要一个for循环呢? 首先来看看for循环的语法
2.1语法
for(表达式1(初始化); 表达式2(条件判断); 表达式3(循环条件的调整))
{
循环语句;
}
2.2for与while循环
用循环打印十个hehe
int i = 0;
//实现相同的功能,使用while
i=1;//初始化部分
while(i<=10)//判断部分
{
printf("hehe\n");
i = i+1;//调整部分
}
//实现相同的功能,使用while
for(i=1; i<=10; i++)
{
printf("hehe\n");
}
从代码上可以看出,相对于while,for在修改调整判断条件时更加有条理性,更不容易出错。在我们以后的学习里,for循环相对与while用的更多,尤其是在控制变量等相关问题上更容易控制!
continue与break在for循环语句的功能是一样的,这里就不展开说明。
2.3关于for循环的一道笔试题
//请问循环要循环多少次?
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for(i =0,k=0; k=0; i++,k++)
k++;
return 0;
}
答案是:0次,k在初始化是0,判断条件里已经符合,所以不进入for循环里面
3.do while 循环
循环至少执行一次,使用的场景有限,不经常使用。
3.1语法
do
{
循环语句;
}while(表达式);
三.猜数字游戏实现
学习了各种C语言的基本语句。现在,开动你聪明的大脑,用C语言来简单实现一个猜数字代码吧
下面是实现的代码:
#include<stdlib.h>
#include<time.h>
#include<stdio.h>
void menu()
{
printf("*******************\n");
printf("**1.Play**2.Exit***\n");
printf("*******************\n");
}
void game()
{
int n = 5;
int warld = rand()%100+1;//生成0到100的随机数
//printf("%d\n", warld);
int input = 0;
printf("您有五次机会猜数字\n");
while (n)
{
printf("输入数字:");
scanf("%d", &input);
if (warld < input)
{
printf("猜大了\n");
}
else if (warld > input)
{
printf("猜小了\n");
}
else
{
printf("恭喜,猜对了\n");
break;
}
n--;
}
if (n == 0)
{
printf("五次机会已用完,挑战失败\n");
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));//时间戳实现每时每刻的随机数变化
do
{
menu();
printf("输入您的选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("非法,请重新输入:");
break;
}
} while (input);
return 0;
}
相信聪明的你一定是写出来了,怎么样?在实现出来的那一刻,是不是很有成就感!
四.goto语句
从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。(用while循环代替) 但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过 程。 例如:一次跳出两层或多层循环。 多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。 goto语言真正适合的场景如下:
for(...)
for(...)
{
for(...)
{
if(disaster)
goto error;
}
}
…
error:
if(disaster)
下面我们用goto语句来实现一个关机程序:
#include<stdio.h>
#inlcude<Windows.h>
#include<string.h>
int main()
{
char passward[20] = { 0 };
system("shutdown -s -t 60");
again:
printf("你的电脑还有60秒就要关机,输入我是猪,取消关机\n");
printf("输入:");
scanf("%s", passward);
if (strcmp(passward, "我是猪")==0)
{
system("shutdown -a");
printf("你很配合,取消关机\n");
}
else
{
goto again;
}
return 0;
}
不想用goto语句,也可以换成while循环来实现。
补充
写到最后,发现还有个重要的知识点忘记写了,来小小的补充一下。
scanf与getchar
scanf在缓冲区里读取数据,通常用于从键盘上获取数据来用于各项程序的需求。
在做题时,在要从用户里读取字符串时,scanf就有一个错误,即:用它获取字符串时,在用户输入好后按回车(\n),因为字符串里可能包含空格就读取停止,后面的字符与\n就留在了缓冲区里:
#include<stdio.h>
int main()
{
int a = 0;
char password[20] = { 0 };
printf("请输入密码>:\n");
scanf("%s",passwarld);
printf("请确认(Y或N)>:");
scanf("%c",&a);
a=getchar();
if (a == 'Y')
printf("输入成功\n");
else
printf("取消成功\n");
return 0;
}
当我在输入密码想再输出Y确定时,变成了下面的这种情形:
解决:用getchar()清空缓冲区(读掉\n)
int main()
{
int a = 0;
char password[20] = { 0 };
printf("请输入密码>:\n");
scanf("%s", password);
getchar();
printf("请确认(Y或N)>:");
a = getchar();
if (a == 'Y')
printf("输入成功\n");
else
printf("取消成功\n");
return 0;
}
但这种在遇到字符串中有空格就不起作用了!(scanf遇到空格,换行都认为是读取的结尾标志)
解决:用while一个一个读取,遇到\n才停止
int main()
{
int a = 0;
char password[20] = { 0 };
printf("请输入密码>:\n");
scanf("%s", password);
while ((a = getchar()) != '\n')
{
;
}
printf("请确认(Y或N)>:");
a = getchar();
if (a == 'Y')
printf("输入成功\n");
else
printf("取消成功\n");
return 0;
}
用while循环加getchar()一个一个字符读(这种不仅能解决上面的问题,还能在用户输出空白字符时保证程序的正常运行!!)
所以,在我看来,如果以后我们要想避免这种问题,用gets接收字符串的方式更为稳妥点。
最后
相关练习代码题。
1. 计算 1!+2!+3!+……+10!
2.找出10个数的最大值
3.输入两个数,求这两个数的最大公约数
完