当前位置: 首页 > news >正文

分支和循环语句

目录

什么是语句?

分支语句(选择结构)

if语句

switch语句

循环语句

while

for

do while

练习

goto语句


 

什么是语句?

C语句可分为以下五类:

1. 表达式语句

2. 函数调用语句

3. 控制语句

4. 复合语句

5. 空语句

本文介绍的是控制语句,控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C言有九种控制语句

可分成以下三类:

1. 条件判断语句也叫分支语句:if语句、switch语句;

2. 循环执行语句:do while语句、while语句、for语句;

3. 转向语句:break语句、goto语句、continue语句、return语句。

分支语句(选择结构)

生活中常常会面临各种选择,我们经常会说,比如如果大学好好学习,就可以找到一份好工作,如果不好好学习,那毕业就等于失业,这就是典型的分支语句

if语句

if语句的语法结构: 

单分支

if(表达式)语句; 
#include <stdio.h>
int main()
{int age;scanf("%d", &age);if (age < 18){printf("未成年\n");}return 0;
}

双分支

if(表达式)语句1;
else语句2;
#include <stdio.h>
int main()
{int age;scanf("%d", &age);if (age < 18){printf("未成年\n");}else{printf("成年\n");}return 0;
}
多分支
if(表达式1)    语句1;
else if(表达式2)语句2;
else语句3;
#include <stdio.h>
int main()
{int age;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");}return 0;
}

注:

1.表达式为真,则语句执行;表达式为假,语句不执行

2.如果 { } 内只有一条语句,那么 { } 可以省略;如果有多条语句,则 { } 不能省略,建议都加上

悬空else问题:

#include <stdio.h>
int main()
{int a = 0;int b = 2;if (a == 1)if (b == 2)printf("hehe\n");elseprintf("haha\n");return 0;
}

我们乍一看认为程序输出haha,实际上什么也没输出,C语言中else的匹配机制是和离自己最近的未匹配的if进行匹配,所以代码风格很重要,如果想让else和第一个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;
}

代码风格对比:

代码一:

#include <stdio.h>
int main()
{int num = 0;if (num == 3){printf("haha\n");}return 0;
}

代码二:

#include <stdio.h>
int main()
{int num = 0;if (3 == num){printf("haha\n");}return 0;
}

建议代码二,因为如果我们不小心把 == 写成了 =,采用代码二写法编译器会直接报错,方便检查

练习:判断一个数是不是奇数

#include <stdio.h>
int main()
{int x;scanf("%d", &x);if (x % 2 == 1){printf("奇数\n");}else{printf("偶数\n");}return 0;
}

switch语句

switch语句也是一种分支语句,常常用于多分支情况,比如:输入1,输出星期一;输入2,输出星期二...输入7,输出星期天,如果使用if语句,分支情况太多,比较麻烦,此时可以用switch语句

switch语句格式

switch(整型表达式)
{case 整型常量表达式:语句;
}

按照上述代码,我们写出的代码如下:

#include <stdio.h>
int main()
{int day;scanf("%d", &day);switch(day){case 1:printf("星期一\n");case 2:printf("星期二\n");case 3:printf("星期三\n");case 4:printf("星期四\n");case 5:printf("星期五\n");case 6:printf("星期六\n");case 7:printf("星期天\n");}return 0;
}

switch中的break语句

当我们输入5的时候,发现星期五、星期六、星期天都被打印出来了,这是为什么呢???

当我们选择从某个case进入后,如果没有遇到break,会一直执行到整个switch语句结束,如果遇到了break,就会提前跳出,因此正确代码应该是给每次打印完后加上break

#include <stdio.h>
int main()
{int day;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;
}

有时候我们的需求变了:

1.输入1-5,输出"weekday"

2.输入6-7,输出"weekend"

代码中我们可以将多个 case 合并到一起,建议在最后一个 case 语句后也加上 break,之所以这么写是可以避免出现在以前的最后一个case语句后忘了添加break语句

#include <stdio.h>
int main()
{int day;scanf("%d", &day);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;
}

switch中的 default 语句

如果我们输入的值与case标签的值都不匹配怎么办?其实也没什么,结构就是所有的语句都被跳过而已。 程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。 但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢?

你可以在语句列表中增加一条default子句,把下面的标签 default写在任何一个 case 标签可以出现的位置。 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。 所以,每个switch语句中只能出现一条default子句。 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

一般建议将 default 子句放在所有case之后,并且也加上一个break

#include <stdio.h>
int main()
{int day;scanf("%d", &day);switch(day){case 1:case 2:case 3:case 4:case 5:printf("weekday\n"); break;case 6:case 7:printf("weekend\n");break;default:printf("输入错误!!!\n");break;}return 0;
}

练习:

#include <stdio.h>
int main()
{int n = 1;int m = 2;switch (n){case 1:m++; //3case 2:n++; //2case 3:switch (n) //switch允许嵌套使用{case 1:n++;case 2:m++; //4n++; //3break;}case 4:m++; //5break;default:break;} printf("m = %d, n = %d\n", m, n); //m = 5, n = 3return 0;
}

注: switch语句嵌套时,break只能跳出当前的switch语句

循环语句

生活中我们经常要重复做一件事情,比如学习计算机,每天都要敲代码,此时就要用到循环语句

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的作用是跳出整个循环,下面代码打印 1 2 3 4

#include <stdio.h>
int main()
{int i = 1;while (i <= 10){if (i == 5)break;printf("%d ", i);i = i + 1;}return 0;
}

continue的作用是跳出本轮循环,不执行cotinue后的代码,直接进入下一次循环,下面代码打印 1 2 3 4 然后就进入了死循环

#include <stdio.h>
int main()
{int i = 1;while (i <= 10){if (i == 5)continue;printf("%d ", i);i = i + 1;}return 0;
}

下面代码打印 2 3 4 6 7 8 9 10 11

#include <stdio.h>
int main()
{int i = 1;while (i <= 10){i = i + 1;if (i == 5)continue;printf("%d ", i);}return 0;
}

再看两段代码:

#include <stdio.h>
int main()
{int ch = 0;while ((ch = getchar()) != EOF)putchar(ch);return 0;
}

getchar用于读取键盘输入的字符,返回该字符的ASCII值,当读取到文件结尾结尾或者读取错误时返回EOF,EOF本质是个宏,值为-1,putchar函数传入字符的ASCII值,可以打印该字符

#include <stdio.h>
int main()
{char ch = '\0';while ((ch = getchar()) != EOF){if (ch < '0' || ch > '9')continue;putchar(ch);}return 0;
}

上面代码可以跳过所有的非数字字符,只打印数字字符

for

for循环语法格

for(表达式1; 表达式2; 表达式3)循环语句;

表达式1为初始化部分,用于初始化循环变量

表达式2为条件判断部分,用于判断循环时候终止。

表达式3为调整部分,用于循环条件的调整。

对比while循环可以发现,while循环也是有这三部分的,但可能这三部分距离比较远,这样查找修改就不够集中和方便,所以for循环的风格更胜一筹,for循环使用的频率也更高

eg:在屏幕上打印1-10

#include <stdio.h>
int main()
{for (int i = 1; i <= 10; i++){printf("%d ", i);}return 0;
}

for循环中的break与continue

for循环中的break与continue,他们两个在for循环中的作用和在while循环中作用是完全一样的,但由于for循环代码风格原因,使用continue时结果可能略有不同

#include <stdio.h>
int main()
{int i = 0;for (i = 1; i <= 10; i++){if (i == 5)continue;printf("%d ", i);}return 0;
}

上面代码打印 1 2 3 4 6 7 8 9 10

#include <stdio.h>
int main()
{int i = 0;for (i = 1; i <= 10; ){if (i == 5)continue;printf("%d ", i);i++;}return 0;
}

for循环的三个表达式不是必须写到一起的,上面代码打印 1 2 3 4,然后死循环

一些for循环的变种

代码一:  for循环的三部分都是可以省略的,但不建议,容易导致问题

#include <stdio.h>
int main()
{for (;;){printf("hehe\n");}return 0;
}

代码二: 嵌套for循环,最终打印9个hehe

#include <stdio.h>
int main()
{int i = 0;int j = 0;//这里打印多少个hehe?for (i = 0; i < 3; i++){for (j = 0; j < 3; j++){printf("hehe\n");}}return 0;
}

代码三: 如果省略掉初始化部分,外层循环循环一次后,j 就会加到3,外层循环的第二次和第三次都不会再进入内层循环的循环体了,最后打印 3个 hehe

#include <stdio.h>
int main()
{int i = 0;int j = 0;for (; i < 3; i++){for (; j < 3; j++){printf("hehe\n");}}return 0;
}

代码四:使用多余一个变量,控制循环,打印2个hehe 

#include <stdio.h>
int main()
{int x, y;for (x = 0, y = 0; x < 2 && y < 5; ++x, y++){printf("hehe\n");}return 0;
}

一道笔试题:

请问循环要循环多少次? 注意判断部分,是赋值符号,因此循环0次

#include <stdio.h>
int main()
{int i = 0;int k = 0;for (i = 0, k = 0; k = 0; i++, k++)k++;return 0;
}

do while

语法格式

do循环语句;
while(表达式);

先执行一次循环语句,然后判断表达式是否成立,决定是否继续循环,因此do while语句的特点是循环体至少执行一次,使用的场景有限,不是很常用

eg: 打印1~10

#include <stdio.h>
int main()
{int i = 1;do{printf("%d ", i);i++;} while (i <= 10);return 0;
}

练习

1. 计算 n 的阶乘

#include <stdio.h>
int main()
{int n; scanf("%d", &n);int ret = 1;for (int i = 1; i <= n; i++)ret = ret * i;printf("%d\n", ret);return 0;
}

2.计算 1!+2!+ ... + n!

#include <stdio.h>
int main()
{int n; scanf("%d", &n);int ret = 0, tmp = 1;for (int i = 1; i <= n; i++){tmp *= i;ret += tmp;}printf("%d\n", ret);return 0;
}

3. 在一个有序数组中查找具体的某个数字n(二分查找)

#include <stdio.h>
int main()
{int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int x;scanf("%d", &x);int l = 0, r = sizeof(a) / sizeof(int) - 1;int mid = 0;while (l <= r){mid = (l + r) / 2;if (x > a[mid]) l = mid + 1;else if (x < a[mid]) r = mid - 1;else{break;}}if(l <= r) printf("找到了, 下标为%d\n", mid);elseprintf("查找的值不存在!\n");return 0;
}

4. 编写代码,演示多个字符从两端移动,向中间汇聚

#include <stdio.h>
#include <windows.h>
#include <string.h>
int main()
{char arr1[] = "welcome to computer world!";char arr2[] = "##########################";int l = 0, r = strlen(arr1) - 1;while (l < r){arr2[l] = arr1[l];arr2[r] = arr1[r];l++, r--;printf("%s\n", arr2);Sleep(1000);}return 0;
}

5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则提示登录成功,如果三次均输入错误,则退出程序)

#include <stdio.h>
#include <string.h>
int main()
{char arr[20];int i = 0;for (;i < 3; i++){scanf("%s", arr);if (strcmp(arr, "password") == 0) //strcmp返回值为0, 代表字符串相等{break;}}if (i == 3)printf("三次密码均错误, 登录失败!\n");elseprintf("登录成功!\n");return 0;
}

6.猜数字游戏

#include <stdio.h>
#include <stdlib.h>void menu()
{printf("#############################\n");printf("######### 0 退出游戏 #########\n");printf("######### 1 开始游戏 #########\n");printf("#############################\n");
}void game()
{int input = 0;int random = rand() % 100;while (1){printf("请输入要猜的数字: \n");scanf("%d", &input);if (input > random)printf("猜大了\n");else if (input < random)printf("猜小了\n");else{printf("恭喜你, 猜中了!\n");break;}}
}int main()
{int input = 0;do{menu();printf("请选择:->\n");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误, 请重新选择\n");break;}} while (input);return 0;
}

goto语句

C语言中提供了可以随意滥用的 goto语句和标记跳转的标号。从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。例如:一次跳出两层或多层循环。多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。

for(...)for(...){for(...){if(disaster)goto error;}}…
error:if(disaster)// 处理错误情况

下面使用 goto 语句 实现了一个关机程序:

#include <stdio.h>
int main()
{char input[10] = { 0 };system("shutdown -s -t 60");
again:printf("电脑将在1分钟内关机,如果输入:我是猪,就取消关机!\n请输入:>");scanf("%s", input);if(0 == strcmp(input, "我是猪")){printf("取消关机!");system("shutdown -a");}else{goto again;}return 0;
}

当然我们完全可以将上述代码改成循环

#include <stdio.h>
#include <stdlib.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;
}

 
http://www.dtcms.com/a/525298.html

相关文章:

  • 自己做网站买株洲平台公司有几家
  • 2.2softmax回归
  • EtherCAT转PROFINET网关在饲料厂自动化系统整合中的关键作用
  • 公司网站建设泉州福田住房和建设局官网
  • 2018建设网站企业网站页脚信息
  • 【Frida Android】基础篇12:Native层hook基础——调用原生函数
  • gitlab上传新仓库,保留原仓库提交记录,原仓库远程地址已经失效,只有本机还有提交记录
  • wordpress最新文章加图标怎么做好网站搜索引擎优化
  • 操作系统 | Linux:第四章 Linux的实用操作
  • 数学概念 复习自用
  • 深圳做h5网站制作ui设计培训是什么
  • 第八章 惊喜18 高绩效辅导之二
  • 22-STM32F103C8T6的WS2812B驱动
  • 做编程网站沈阳做企业网站的
  • 网站内容栏目网站建设全
  • LeetCode:1905. 统计子岛屿
  • 数据库研发规范
  • esp-idf 最简操作
  • 专业网站建设设计服务开发公司五一节前安全生产工作部署会
  • PY32F040单片机介绍(4)
  • 网站建设氵金手指下拉十三北京专业网站翻译影音字幕翻译速记速记速记速而高效
  • Qualcomm SNPE(Neural Processing SDK)集成到 OpenWRT + QCS6490 的完整配置后续
  • 多平台终端模拟器
  • wordpress建站网站根目录百度竞价托管一月多少钱
  • wordpress如何仿站wordpress文件夹改名
  • kotlin中的let的使用
  • 计算机视觉领域应用了模块缝合思想的经典模型
  • Kubernetes Calico 网络故障排查与修复:RBAC 权限问题完整解决记录
  • Orleans 客户端与 Silo 配置方式深度分析
  • RecyclerView设置空布局