C语句可分为以下五类:
控制语句用于控制程序的执行流程,以实现程序的各种结构方式。C语言支持三种结构:
它们由特定的语句定义符组成,C语言有九种控制语句。可分成以下三类:
if语句的语法结构可以分为单分支结构,双分支结构和多分支结构。
单分支 双分支 多分支
if(判断表达式) if(判断表达式) if(判断表达式1)
{ { {
语句列表; 语句列表1; 语句列表1;
} } }
else else if(判断表达式2)
{ {
语句列表2; 语句列表2;
} }
else
{
语句列表3;
}
这里的一对{}称为一个代码块,建议无论语句列表是一句代码还是多句,都带上{}。
如果表达式的结果为真,则语句执行。在C语言中,0表示假,非0表示真。实例如下:
else 与离它最近的 if 匹配。
适当地使用{}可以使代码的逻辑更清楚,避免一些阅读程序的误会。
代码风格非常重要,好的代码风格不但可以让阅读代码的读者清晰的理解,而且可以使自己的思维逻辑更加清晰不容易出错,推荐书籍《高质量的C/C++编程》。
简单举两个例子(两个例子中的代码1和代码2输出结果均相同):
用{}使代码误读率下降。
代码1 代码2
if(判断表达式) if(判断表达式)
{ {
return x; return x;
}
else }
{
return y; return y;
}
//推荐 //不推荐
在比较变量和常量是否相等时,写为 常量==变量 的形式,可以有效避免一些代码问题。
代码1 代码2
int num = 1 ; int num = 1;
if(5 == num) if(num == 5)
{ {
printf("JX\n"); printf("JX\n");
} }
//推荐 //不推荐
switch语句也是一种分支语句。常常用于多分支的情况。
switch的构造如下:
switch 在圆括号中的表达式值是一个整数值(包括char类型),case 标签必须是整数类型(包括char类型)的常量或整形常量表达式,不可以用变量来作为 case 的标签。
switch(整形表达式)
{
case 常量1:
语句;
case 常量2:
语句;
default:
语句;
}
在switch语句中,我们没办法直接实现分支,搭配break使用才能实现真正的分支。
#include <stdio.h> #include<stdio.h>
int main() int main()
{ {
int day = 0; int day = 0;
scanf("%d",&day); scanf("%d",&day);
switch(day) switch(day)
{ {
case 1: case 1:
printf("星期一\n"); case 2:
break; case 3:
case 2: case 4:
printf("星期二\n"); case 5:
break; printf("周内\n");
case 3: break;
printf("星期三\n"); case 6:
break; case 7:
case 4: printf("周末\n");
printf("星期四\n"); break;
break; default:
case 5: printf("输入错误\n");
printf("星期五\n"); break;
break; }
case 6: return 0;
printf("星期六\n"); }
break;
case 7:
printf("星期天\n");
break; 好习惯:
default: < —————— 在 switch 语句中都放一条default子句,
printf("选择错误\n"); 可以在后面加一个break。
break;
}
return 0;
}
break语句实际效果是把语句列表划分为不同的分支部分。break 语句是 switch 语句的出口,让程序离开 switch 语句,跳转到其下一条语句,如果没有 break 语句,就会从匹配标签的第一个case开始一直执行到 switch 末尾。
顺便总结一下,break 语句既可以用于循环语句中同时也可以用于 switch 语句中,但 continue 只能用于循环中。如果 switch 语句在一个循环中,continue 就可以作为 switch 语句的一部分,就像在其他循环一样,continue 让程序跳出循环的剩余部分,包括 switch 语句的其他部分。
如果表达的值与所有的case标签的值都不匹配怎么办?
其实也没什么,结构就是所有的语句都被跳过而已。程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?你可以在语句列表中增加一条default子句,把标签 default: 写在任何一个 case 标签可以出现的位置。当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。所以,每个switch语句中只能出现一条default子句。但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。
好习惯:在每个 switch 语句中都放一条default子句是个好习惯,甚至可以在后边再加一个 break 。
#include <stdio.h> //switch允许嵌套使用
int main()
{
int n = 1;
int m = 2;
switch (n)
{
case 1:
m++;
case 2:
n++;
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的语法结构: while(判断表达式)
{
循环语句;
}
具体实现为,如果判断表达式为真,执行循环语句一次,然后返回判断表达式再次判断;在判断表达式为假之前,循环的判断和执行一直重复进行,每一次循环都被称为一次迭代。图解如下:
了解了while的工作流程,就来实现一下在屏幕打印1~10的数字。
break在while循环中的作用:
其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。所以:while中的break是用于永久终止循环的。
continue在while循环中的作用就是:
continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。
对于scanf和getchar这样的输入函数,它们若想得到输入的内容,是这样进行的:你先在键盘上将所输入的东西打到缓冲区中,然后再将缓冲区中的内容传递给了输入函数。也就是说还有一个缓冲区。
由于 getchar() 和 putchar() 这两个函数只处理字符,所以它们比通用的 scanf() 和 printf() 函数更快、更简洁。并且这两个函数不需要转换说明,因为它们只处理字符。它们定义在 stdio.h 头文件中,比较特殊的是,getchar() 和 putchar() 通常是预处理宏,不是真正的函数。
for(表达式1(变量初始化); 表达式2(判断表达式); 表达式3(调整变量))
{
循环语句;
}
我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。但是结果就不一样了。
建议:
int i = 0;
//前闭后开的写法
for(i=0; i<10; i++)
{...}
//两边都是闭区间
for(i=0; i<=9; i++)
{...}
for循环中的初始化部分,判断部分,调整部分是可以省略的,但是不建议初学时省略,容易导致问题。
do
{
循环语句;
}
while(判断表达式);
循环至少执行一次,但使用的场景有限,所以不是经常使用。
跟前面的while和for几乎是一样的,直接上例子。
C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。
但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如:一次跳出两层或多层循环。
多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。
goto语言真正适合的场景如下:
for(...)
{
for(...)
{
for(...)
{
if(disaster)
goto error;
}
....
}
}
error:
if(disaster)
{
// 处理错误情况
}
下面是使用goto语句的一个关机程序,然后再使用循环的实现方式替换goto语句:
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input[10] = { 0 };
system("shutdown -s -t 60");
again:
printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");
scanf("%s", input);
if (0 == strcmp(input, "我是猪"))
{
system("shutdown -a");
}
else
{
goto again;
}
return 0;
}
而如果不适用goto语句,则可以使用循环:
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char input[10] = { 0 };
system("shutdown -s -t 60");
while (1)
{
printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");
scanf("%s", input);
if (0 == strcmp(input, "我是猪"))
{
system("shutdown -a");
break;
}
}
return 0;
}