您现在的位置是:首页 >其他 >【C语言+代码风格】认识分支与循环语句及代码风格网站首页其他
【C语言+代码风格】认识分支与循环语句及代码风格
?纸上得来终觉浅, 绝知此事要躬行。
?主页:June-Frost
?专栏:C语言
⚡注:此篇文章的 代码风格部分 将根据《高质量 C++/C 编程指南》 —— 林锐 进行说明。该部分将用紫色表示
此篇文章将详细说明分支与循环语句 以及它们的 代码风格
文章目录:
c语言是结构化的程序设计语言,支持三种结构,即 顺序结构 ,选择结构 , 循环结构 。
语句的分类
C语言的语句可以分为5类:
1.表达式语句;
2.函数调用语句;
3.控制语句;
4.复合语句;
5.空语句;
控制语句 用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句。
将其分为3类:
- 分支语句(条件判断):if语句,switch语句;
- 循环执行语句:do while语句 , while语句,for语句。
- 转向语句:break语句,goto语句,continue语句,return语句。
良好的代码风格:
像 if、for、while 等关键字之后应留一个空格再跟左括号‘(’,以突出关键字。
分支语句
分支语句支持选择结构。
例如:进入图书馆选择书籍就是一种选择。
if 语句
?if语句的语法结构为:
<单分支>
if (condition)
statement;
<双分支>
if (condition)
statement1;
else
statement2;
<多分支>
if (condition)
statement1;
else if
statement2;
else
statement3;
?对于if 语句的使用 举个例子:判断成年
<单分支>
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年
");
return 0;
}
如果要判断出来是成年的话,做事需要完全承担责任。
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
printf("成年
");
printf("做事完全承担责任
");
return 0;
❗️结果:
我们可以发现 结果出现了问题。
if语句 默认情况下会控制一条语句,如果要控制多条语句,需要用{},也即是复合语句。
正确书写:
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age >= 18)
{
printf("成年
");
printf("做事完全承担责任
");
}
return 0;
}
if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论执行语句有多少都要加{}。这样可以防止书写失误。
以下代码均为该形式
?例子:判断年龄
<双分支>
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if (age < 18)
{
printf("未成年
");
}
else
{
printf("成年
");
}
return 0;
}
?判断多个年龄:
#include<stdio.h>
int main()
{
int age = 0;
scanf("%d", &age);
if ((age>0) && (age<14))
{
printf("儿童
");
}
else if ((age >= 14) && (age < 35))
{
printf("青年
");
}
else if ((age >= 35) && (age < 65))
{
printf("中年人
");
}
else
{
printf("老年人
");
}
return 0;
}
?注意:
对于表达式比较长的 if 语句,为了紧凑起见可以适当地去掉一些空格。例如:
if ((age>0) && (age<14))
但是不要写成if((age>0)&&(age<14))
。
不要把程序中的复合表达式与“真正的数学表达式”混淆。例如:表示年龄在 0到14之间不可以写为 0<age<14,这是数学表达式,在程序中这样子的表达式 会被理解为(0<age)<14 。 在执行时,若输入age为10 ——> 10>0 ——> (0<age)的结果就是1——> 1<14 这个式子就会永远为真。 所以需要写成
if ((age>0) && (age<14))
。
?if语句可以嵌套:
例如:
if ((age>0) && (age<14))
{
printf("儿童
");
}
else
{
if ((age >= 14) && (age < 35))
{
printf("青年
");
}
else if ((age >= 35) && (age < 65))
{
printf("中年人
");
}
else
{
printf("老年人
");
}
}
注意:在c语言中,0为假,非0为真。
悬空else
代码示例:
#include<stdio.h>
int main()
{
int a = 0;
int b = 2;
if (a == 1)
if (b == 2)
printf("点赞
");
else
printf("收藏
");
return 0;
}
❗️结果如下:
注意: else 会和 最近的if 匹配 。 最好加入{} ,使得代码中的匹配更加明确。
switch 语句
?switch语句语法:
switch(整形表达式)
{
语句项;
}
?语句项是一些case语句:
case 整形常量表达式:
语句;
❓ if语句已经可以完成选择,switch存在的理由是什么呢?
❗️switch 是多分支选择语句。如果有大量的分支,if…else if…else 这样的结构就会显得冗长。这时候switch就可以使用了。
举个例子:
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一");
break;
case 2:
printf("星期而");
break;
case 3:
printf("星期三");
break;
case 4:
printf("星期四");
break;
case 5:
printf("星期五");
break;
case 6:
printf("星期六");
break;
case 7:
printf("星期日");
break;
}
return 0;
}
case 决定入口,break决定出口。整形变量的值决定从哪个入口进入。
break既然决定出口,那么就可以根据需求建立出口。
例如 需求为:
- 输入1-5,输出的是“weekday”;
- 输入6-7,输出“weekend”;
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday
");
break;
case 6:
case 7:
printf("weekend
");
break;
}
return 0;
}
default子句
如果表达式的值和case的标签都不一样,这种情况下,结构中的所有语言都会被跳过,这种情况下c语言并不会报错,但是如果不想忽略不匹配的值,就可以使用default字句。
即使程序真的不需要 default 处理,也应该保留语句 default 。甚至可以加个break 。
所以良好的习惯风格:
#include<stdio.h>
int main()
{
int day = 0;
scanf("%d", &day);
switch (day)
{
case 1:
case 2:
case 3:
case 4:
case 5:
printf("weekday
");
break;
case 6:
case 7:
printf("weekend
");
break;
default:
printf("输入错误
");
break;
}
return 0;
}
循环语句
- while循环
- for 循环
- do while 循环
while 循环
while语句的语法结构: while(表达式)循环语句;
✍while语句的执行流程
举个例子 : 打印 1 到 10
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
return 0;
}
结果:
while语句中的break和continue
博主会用两个例子来说明功能:
❗️break是用来永久终止循环的。在某些条件产生后想终止循环,就可以使用break,一次只能跳出一层循环。
可以观察到,在打印出4后,该循环变为死循环,这是因为continue可以跳过本次循环后面的代码,再次进行判断,由于i++ 被跳过,i只能为5,造成死循环。
❗️continue 跳过本次循环在continue之后的代码,直接进入while循环的判断部分。
while语句的应用
了解getchar和putchar
getchar 用来获取一个字符,不需要参数,返回字符的ASCLL码值。
如果正确读取到一个字符,则返回ASCll码值,如果读取不正常,则会返回EOF(end of file,文件结束标志),EOF其实就是 -1 。
为什么接收值为 int 而不是 char 呢?
?对于char类型,一些编译器定义的范围为 -128 ~ 127,还有一些为 0~255 。如果是后者,在返回 -1 时就会出错,另外,对于ASCll码表的扩展字符,就算时 -128 ~ 127 也无法表示,所以采取大范围的 int 更加合适。
putchar 只能打印字符,参数可以为ASCll码值。
?举个例子:<输入密码>
#include<stdio.h>
int main()
{
printf("请输入密码:>");
char password[20] = { 0 };
scanf("%s", password);
//清空缓冲区·
while (getchar() != '
')
{
;
}
char input = 0;
printf("请确认(Y/N):> ");
scanf("%c", &input);
if ('Y' == input)
{
printf("确认成功
");
}
else
{
printf("确认失败
");
}
return 0;
}
❗️结果:
这里需要注意输入缓冲区
?下图为对该程序中输入缓冲区的变化
for循环
影响循环的有三个因素:循环变量的初始化,判断,调整。
for存在的意义:
for循环可以将这三个因素整合在一起,比较集中,这就是一种相比while循环的一种优势。
for循环的语法结构:
for (表达式1; 表达式2; 表达式3)
循环语句;
表达式1 —— 初始化;
表达式2—— 判断;
表达式3——调整;
✍for语句的执行流程:
好的代码习惯如下:
if、for、while、do 等语句自占一行,执行语句不得紧跟其后。不论
执行语句有多少都要加{}。这样可以防止书写失误
如果‘;’不是一行的结束符号,其后要留空格,如 for (initialization; condition; update)。
对于表达式比较长的 for 语句,为了紧凑起见可以适当地去掉一些空格,如
for (i=0; i<10; i++)不要写成for(i=0;i<10;i++)和for (i = 0; I < 10; i ++)。
我们可以按照此要求写一个循环打印 1-10。
#include<stdio.h>
int main()
{
int i = 0;
for (i=1; i<=10; i++)
{
printf("%d ", i);
}
return 0;
}
如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
? 如果N(循环次数)大,可以采用该方式,不会打断“流水线”作业,能提高效率。
if (condition)
{
for (i=0; i<N; i++)
{
//业务处理
}
}
else
{
for (i=0; i<N; i++)
{
//业务处理
}
}
如果N比较小,两者差别不明显。以下这种更加简洁。
for (i = 0; i < N; i++)
{
if (condition)
{
//业务处理
}
else
{
//业务处理
}
}
for循环中的break和continue
for循环中的break和continue的意义与while循环的一致。但是对于continue有时会有不同的结果,例如:
对于上面类似的代码,while循环的continue 会使得代码变为死循环,while循环的continue使得调整部分被跳过,但是由于for循环的调整部分不在循环体内,所以不会造成死循环。
对于for循环写法:
不可在 for 循环体内修改循环变量,防止 for 循环失去控制。循环变量的调整只放在表达式3中可以防止出现问题。
建议 for 语句的循环控制变量的取值采用“半开半闭区间”写法。虽然for (i=0; i<=9; i++)和for (i=0; i<10; i++)都是循环10次,但是第二个更加直观。
表达式的省略带来的结果
- 初始化和调整部分的省略就是什么都不执行;
- 判断部分的省略即为判断恒为真;
do while循环
do while 循环语法结构:
do
循环语句;
while(表达式);
✍do while语句的执行流程:
特点:
循环至少执行一次。
do while 循环中的break和continue
可以见得:
与while和for 循环的break和continue的意义一致。
goto语句
C语言中提供了可以随意滥用的goto语句和标记跳转的标号。只要在一个函数内,就可以任意跳转。
例如:
❗️goto语句如果大量使用,会导致逻辑不容易把控。
✍goto语句有自己的应用场景:最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。
例如:
for (...)
{
for (...)
{
for (...)
{
if (condition)
{
goto error;
}
}
}
}
error:
...
本来需要3次break才可以跳出,现在只需要一个goto就可以直接跳出。