目录
1.什么是语句?
c语言语句可以分为五类:
1.1表达式语句
例如“2+3”这种表达式
1.2函数调用语句
例如:
do
{
//打印菜单
menu();
//选择玩游戏或退出
scanf("%d", &input);
switch (input)
{
//选择0,退出游戏
case 0:
printf("退出游戏\n");
break;
//选择1,开始游戏
case 1:
game();
break;
}
} while (input);
这段代码中打印菜单"menu();”和进行游戏"game();”就是 调用自定义函数的 函数调用语句。
1.3控制语句
这是本文后面着重讲的内容(敲黑板啦)
控制语句用于控制程序的执行流程,以实现程序的各种结构方式(顺序结构,选择结构和循环结构),它们由特定的语句定义符组成,c语言有九种控制语句。可分为以下三类:
1.4复合语句
复合语句就是把多个语句用括号{}括起来组成的一个语句。例如:
{
int a = 0;
int b = 2;
printf("hehe\n");
printf("haha\n");
}
需要注意的是,C语句中除复合语句外的其他所有都以分号结束。
1.5空语句
顾名思义,就是什么都没有的语句啦。只有一个分号构成的语句叫做空语句。
;
当你需要有一行代码什么都不执行的时候会用到哒。
2.分支语句(选择结构)
既然是选择结构,当然是面对多种情况做出的选择。假如你从高处往下跳,就会有多种不同的情况。我们可以用下图较为清晰地表现这种结构:
(小朋友们不要模仿哦)
那我们怎样才能用c语言的分支语句表现这种结构呢?这就要用到我们的条件判断语句。
2.1 if语句
2.1.1 语法结构
if语句基本语法结构如下:
下面我们来举几个实际的例子来深入理解一下:
//判断未成年人
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d". &age);
if (age < 18)
{
printf("未成年\n");
}
return 0;
}
这个代码中,如果输入的数字小于18,就会打印“未成年”,否则,不执行if后面的语句。
//判断两个数大的小关系
#include<stdio.h>
int main()
{
int x = 0;
int y = 0;
while (scanf("%d %d", &x, &y) != EOF)
{
if (x > y)
{
printf("%d>%d\n", x, y);
}
else if (x < y)
{
printf("%d<%d\n", x, y);
}
else
{
printf("%d=%d\n", x, y);
}
}
return 0;
}
这个代码中,满足第一个条件,就执行第一个语句,而后面的都不执行。只有前面的条件不满足,才会执行后面的语句。
表达式的结果为真,则语句执行;表达式结果为假,表达式不执行。
c语言中0表示假,非0表示真。
例如:
#include<stdio.h>
int main()
{
int i = 0;
if (1)
i++;
printf("%d\n", i);
return 0;
}
结果为1
这里的if(1)中表达式始终是1,所以一定会执行,而如果表达式是0,则不会执行。
2.1.2 表达式判断多条件
现在我们知道多分支的if语句如何使用了,大家可以拿下面这个问题练练手:
一个人如果年龄 age<18,输出“少年”;如果 18=<age<30,输出“青年”;如果 30=<age<50,输出“中年”;如果 50=<age<80,输出“老年”;如果 age>80,输出“老寿星”。
直接上代码:
#include <stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("少年\n");
}
else if (18 <= age < 30)
{
printf("青年\n");
}
else if (30 <= age < 50)
{
printf("中年\n");
}
else if (50 <= age < 80)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
}
当我们输入25时,输出“青年”,似乎很合理。
然而当我们输入35时,却依然输出“青年”,这是怎么回事呢?
原来,if后面表达式是从左向右执行的,当我们输入35时,先判断 35<=age,表达式结果为假,即表达式结果为0;接下来再比较 0<age,表达式结果为真,于是执行该分支,而后面的分支由于是else if,所以不再执行。
所以,在if的表达式判断处要判断多个条件时,我们最好使用&&连接,以防出错。
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("少年\n");
}
else if (age >= 18 && age < 30)
{
printf("青年\n");
}
else if (age >= 30 && age < 50)
{
printf("中年\n");
}
else if (age >= 50 && age < 80)
{
printf("老年\n");
}
else
{
printf("老寿星\n");
}
}
用以上这种代码,就不会出现上述问题。
2.1.3 else的匹配
else使用时,可能会出现“悬空else”的情况,即else要与上上一个if相匹配:
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("%d\n",a);
else
printf("%d\n",b);
return 0;
}
这里到底是输出“0”还是“1”呢?
其实,这段代码什么也不会输出。这里写代码本意是想将else与第一个if相匹配, 然而,else只与离它最近的if相匹配,所以第一个if不执行,代码直接结束。
那如何才能满足原来的思路呢?
其实只需要将不想匹配的if语句用“{}”括起来即可。
#include <stdio.h>
int main()
{
int a = 0;
int b = 2;
if(a == 1)
{
if(b == 2)
{
printf("%d\n",a);
}
}
else
{
printf("%d\n",b);
}
return 0;
}
2.1.4 if书写形式
从刚刚的错误中我们可以意识到,代码的风格和排版很重要,敲代码一定要养成好习惯。那么什么样的代码是好代码呢?我们来比较一下下面的几种代码。
以刚开始的“跳楼”为例:
//代码1
if (floor<=2)
{
printf("没事");
}
printf("有事");
//代码2
if(floor<=2)
{
printf("没事");
}
else
{
printf("有事");
}
两种代码结果是一样的,但是代码2的结构更加清晰,不容易出错。适当的使用{}可以使代码的逻辑更加清楚。
再来看一组:
//代码3
if(floor == 8)
{
printf("G");
}
//代码4
if(8 == num)
{
printf("G");
}
这两个代码结果也是一样的,但是代码4的习惯更好,因为假如判断的“==”不小心被写成赋值的“=”,代码3会直接运行导致错误,而代码4会报错不能运行,从而更容易找出错误。将"=="写在变量的前面可以避免不必要的麻烦。值得注意的是,如果判断的是一个表达式,不论写在前面还是后面,只要中间是赋值的“=",都会报错。
2.2 switch语句
switch语句也是一种分支语句,常用于多分支的情况。
2.2.1 语法结构
我们可以通过下面的例子来理解一下
#include<stdio.h>
int main()
{
int floor = 8;
switch (floor)
{
case 1:
printf("没事\n");
case 3:
printf("重伤"\n);
case 8:
printf("G"\n);
}
return 0;
}
这段代码中,由于floor是8,直接执行case 8:后面的语句,结果为”G“。
然而,如果floor大小为1,三个语句都会执行;如果floor大小为3,后两个语句都会执行。可见,switch语句中,语句是从switch后面的整型表达式相对应的case语句“开始”执行的。那么怎样才能只执行单个相应的语句呢?
2.2.2 switch语句中的break
在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。
对刚才的代码稍作修改,得到以下代码:
#include<stdio.h>
int main()
{
int floor = 8;
switch (floor)
{
case 1:
printf("没事\n");
break;
case 3:
printf("重伤"\n);
break;
case 8:
printf("G"\n);
break;
}
return 0;
}
在有break的情况下,对应语句执行完毕,遇到break就会跳出switch语句,从而实现真正的分支。
当然,有时候我们会遇到多个条件执行一个语句的情况,用switch语句也能实现:
#include<stdio.h>
int main()
{
int floor = 8;
switch (floor)
{
case 1:
case 2:
printf("没事\n");
break;
case 3:
case 4:
printf("重伤"\n);
break;
default:
printf("G"\n);
break;
}
return 0;
}
break语句的实际效果是把语句列表划分为不同的分支部分。
当你写完一个switch语句之后,最后一个case语句没有加break,对当前代码是没有什么影响的。但是以后有可能会添加更多的分支,这个过程中前面没有break可能会被遗忘。因此我们要养成switch语句中case语句后加上break的好习惯。
2.2.3 default子句
在switch语句中,如果每一个case标签的值都与表达式不匹配会怎样呢?
根据该语句的逻辑,所有的case语句都会被跳过。程序不会终止,也不会报错(在c中并不是一种错误)。但是如果我们想让程序结束或执行其他语句该怎么办呢?
相信大家已经看到了上一个代码中出现的"default"。default子句使用方式与case语句几乎完全一样,可以写在任何一个case语句可以出现的位置,当所有的case标签值都与表达式不匹配时,default语句就会执行,所以每个switch语句中只能出现一个default子句。当然,如果您前面的子句没有加break,所有子句包括default子句都只会按从前往后的顺序执行。
这里提醒一下大家,在每个switch语句中都加上default语句是一种好习惯哦!别忘了加break!!
(未完待续)