第二章-分支语句和循环语句
C语言是结构化的程序设计
顺序结构 —— 选择结构 (分支语句 if、switch)—— 循环结构(循环语句 while、
for、do while)
一、语句
C语言中由一个分号(;)隔开就是一条语句。
二、分支语句(选择结构)
1. if语句
注、C语言是如何表示真和假的?
非0就是真,0就是假
(1)语法形式
Ⅰ 类型1
if(表达式) 语句;
#include<stdio.h> int main() { int age =20; if (age < 16) printf("未成年\n"); return 0; }
Ⅱ 类型2——双分支
if(表达式) 语句1; else 语句2;
#include<stdio.h> int main() { int age = 20; if (age < 18) printf("未成年\n"); else printf("成年\n"); return 0; }
Ⅲ 类型3——多分支语句
if(表达式1) 语句1; else if(表达式2) 语句2; else 语句3;
#include<stdio.h> int main() { int age = 20; if (age < 18) printf("未成年\n"); else { if (age >= 18 && age < 25)//(18<=age<28)错误 //&& -- 逻辑与 // a&&b,a和b都为真时 式子才返回true,否则就返回false printf("青年\n"); else if (age >= 28 && age < 50) printf("壮年\n"); else (age >= 50) printf("老年\n"); } return 0; }
#include<stdio.h> int main() { int age = 20; if (age < 18) printf("未成年\n"); else if (age >= 18 && age < 25)//(18<=age<28)错误 printf("青年\n"); else if (age >= 28 && age < 50) printf("壮年\n"); else printf("老年\n"); return 0; }
注:代码块,执行多条语句,使用{ }将语句组成一个整体
(2)悬空else
#include<stdio.h> int main() { int a = 0; int b = 0; if (a == 1)//a=0,未进去,后面不存在 if (b == 2) printf("hehe\n");//不打印 else//与最近的未匹配的if匹配 printf("haha\n");//不打印 return 0; }
修改后
#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; }
(3)if书写形式的对比
//代码1 if (condition) { return x; } return y; //代码2 if(condition) { return x; } else { return y; } //本质一样,代码2更容易理解
//代码1 int num = 1; if(num == 5) { printf("hehe\n"); } //代码2 int num = 1; if(5 == num) { printf("hehe\n"); } //代码2更好 //两个整型变量比较 //常量放左边 //更容易检验出是赋值还是比较
(4)练习
1. 判断一个数是否为奇数
2. 输出1-100之间的奇数
#include<stdio.h> int main() { //判断一个数是否为奇数 //输出1-100之间的奇数 int i = 1; for (i=1; i<= 100;i++) { if (i % 2 == 1) printf("%d,", i); } return 0; }
//while语句 #include<stdio.h> int main() { int i = 1; while (i <= 100) { if (i % 2 == 1) printf("%d,", i); i++; } return 0; }
2.switch语句
switch语句,用于多分支
(1)语法形式
switch(整型表达式) { 语句项; }
//语句项 //是一些case语句: case 整形常量表达式: 语句;
例
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int day = 0; scanf("%d", &day);//2 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; }
注:break语句,是把语句列表划分为不同的分支部分
在最后一个 case 语句的后面加上一条 break语句,避免出现忘了添加 break语句。
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> //1. 输入1-5,输出的是“工作日y”; //2. 输入6-7,输出“休息日” int main() { int day = 0; scanf("%d", &day); switch(day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; } return 0; }
(2)default子句
对不匹配所有标签的表达式的值,进行报错
#include<stdio.h> int main() {switch (n) { case 1: ...... default: break; } return 0; }
(3)练习
#include<stdio.h> int main() { int n = 1; int m = 2; switch (n) { case 1: m++;//3 case 2: n++;//2 case 3: switch (n)//n=2 {//switch允许嵌套 case 1: n++; case 2: n++;//3 m++;//4 break; } case 4: m++;//5 break; default: break; } printf("m=%d,n=%d\n", m, n);//5,3 return 0; }
三、 循环语句
1. while循环
(1)语法形式
while(表达式)//表达式为真,循环语句执行 循环语句;
例、在屏幕上打印1-10的数字
#include<stdio.h> int main() { int i = 1; while (i<=10) { printf("%d",i); i++; } return 0; }
(2)break和continue
#include<stdio.h> int main() { int i = 1; while (i<=10) { if (i == 5) break;//在while中,break是终止,停止后期所有循环,直接终止循环 //continue;//continue是循环,终止本次循环,跳过后面代码,到判断部分,进入下一次循环入口 printf("%d",i);//1234( break);1234,后面是死循环(continue) i++; } return 0; }
(3)练习
#include<stdio.h> int main() { int ch = 0; //getchar读取一个从标准输入(键盘)的字符,返回整型int(ASCII和-1) //正确读取,返回ASCII,错误读取,返回EOF //EOF-end of file文件结束标志,本质为-1 while ((ch = getchar()) != EOF) //getchar读取的字符,放入ch //不等于(!=)EOF,输出ch putchar(ch);//putchar--输出一个字符 return 0;//就读取结束,敲CTRL+Z }
输入函数(例:getchar)和键盘之间存在一个缓冲区,从缓冲区获取数据。
//问题代码 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { char password[20] = { 0 }; printf("请输入密码:>"); scanf("%s", password);//输入密码,并存放在password数组中 //缓冲区还剩余一个“/n” printf("请确认(Y/N):>");//问题出在敲出密码后,回车“\n”,ASCII为10,应该清除数据或者清空 int ret = getchar();//Y/N if (ret == 'Y') { printf("确认成功\n"); } else { printf("放弃确认\n"); } return 0; }
修改后
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { char password[20] = { 0 }; printf("请输入密码:>"); scanf("%s", password); //清除缓冲区 //添加getchar();可消除 getchar(); printf("请确认(Y/N):>"); int ret = getchar();//Y/N if (ret == 'Y') { printf("确认成功\n"); } else { printf("放弃确认\n"); } return 0; }
优化
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int ret = 0; char password[20] = { 0 }; printf("请输入密码:>"); scanf("%s", password); int ch = 0; //能够消除缓冲区的多个字符"\n" while((ch=getchar())!='\n') { ; } printf("请确认(Y/N):>"); ret = getchar();//Y/N if (ret == 'Y') { printf("确认成功\n"); } else { printf("放弃确认\n"); } return 0; }
#include <stdio.h> int main() { char ch = '\0'; while ((ch = getchar()) != EOF) { if (ch < '0' || ch > '9') //只打印数字字符,跳过其他字符的 //输入a,不打印 continue; putchar(ch); } return 0; }
2. for
//while 循环的缺点 //间距过长,容易失误 #include<stdio.h> int main() { int i = 0;//初始化 while (i < 10)//判断 { i++;//调整 } return 0; }
(1)语句形式
for(表达式1; 表达式2; 表达式3) 循环语句;
- 表达式1为初始化部分,用于初始化循环变量的。
- 表达式2为条件判断部分,用于判断循环时候终止。
- 表达式3为调整部分,用于循环条件的调整。
例:打印1-10的数字
#include<stdio.h> int main() { int i = 0; // 初始化 判断 调整 for (i = 1; i <= 10; i++) { printf("%d", i); } return 0; }
(2) break和continue
#include <stdio.h> int main() { int i = 0; for (i = 1; i <= 10; i++) { if (i == 5) break;//1234后,跳出循环 //continue;//1234后,跳到i++,即调整部分 printf("%d ", i);//1234(break);1 2 3 4 6 7 8 9 10(continue) } return 0; }
(3)循环控制变量
1.不可在for循环内修改循环表里,防止for循环失去控制
#include<stdio.h> int main() { int i = 0; for (i = 1; i <= 10; i++) { if (i = 5)//这里禁止修改 printf("%d", i); //i=5;//这里禁止修改变量 //循环内部改变循环变量,会出现死循环 } return 0; }
2.建议for语句的循环控制变量的取值采用“前闭后开区间”写法
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; ///前闭后开 for (i = 0; i < 10; i++) { printf("%d", arr[i]);//12345678910 } return 0; }
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; ///前闭后闭 for (i = 0; i <= 9; i++) { printf("%d", arr[i]);//12345678910 } return 0; }
更容易看出循环10次
(4)一些for循环的变种
#include<stdio.h> int main() { for (;;)//判断省略,条件恒为真,造成死循环 { printf("hehe\n"); } return 0; }
#include<stdio.h> int main() { int i = 0; int j = 0; //这里打印多少个hehe? //10*10个 for (i = 0; i < 10; i++) { printf("%d", i); int j = 0; for (j = 0; j < 10; j++) { printf("hehe\n"); } } return 0; }
#include<stdio.h> int main() { int i = 0; int j = 0; //这里打印多少个hehe? //10个 //省略掉初始化部分 for (; i < 10; i++) { //int j = 0; for (; j < 10; j++) { printf("hehe\n"); } } return 0; }
#include<stdio.h> int main() { //使用多余一个变量控制循环 //2个hehe int x, y; for (x = 0, y = 0; x < 2 && y < 5; ++x, y++) { printf("hehe\n");//hehe hehe } return 0; }
( 5)笔试题
//循环几次 0次 #include<stdio.h> int main() { int i = 0; int k = 0; for (i = 0, k = 0; k = 0; i++, k++)//k=0,把0赋值给k,0为假 k++; return 0; }
3.do while()循环
(1)语句形式
do 循环语句; while(表达式);
例:打印1、2、3、4、5、6、7、8、9、10
#include <stdio.h> int main() { int i = 1; do { printf("%d", i);//12345678910 i++; } while (i <= 10); return 0; }
和while的区别:
- while先判断在执行
- do while是先执行后判断
(2)break和continue
#include <stdio.h> int main() { //1-10 int i = 1;//1、创建变量 do { if (i == 5) break;//1,2,3,4 //continue 1.2.3.4死循环,跳过后面代码 printf("%d\n", i);//3. i++;//4 } while (i <= 10);//2. return 0; }
4. 练习
1. 计算 n的阶乘。
//计算阶乘 //n!=1*2*...*(n-1)*n #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int i = 0; int n = 0; int ret = 1; scanf("%d", &n);//100 for (i = 1; i <= n; i++) { ret *= i; } printf("ret =%d\n", ret); return 0; }
2. 计算 1!+2!+3!+……+10!
//方法 1 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int i = 0; int n = 0; int ret = 1; int sum = 0; //1+2+6=9 for (n = 1;n <= 3; n++) { ret = 1;//不赋值,会变 for (i = 1; i <= n; i++)//产生1-n的数 { ret = ret * i;//将i累乘赋值给ret } sum = sum + ret; } //ret=1*1 //ret=1*1*2 //ret=1*1*2*3 printf("sum=%d\n", sum); return 0; }
//方法2 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main() { int i = 0; int n = 0; int ret = 1; int sum = 0; //1+2+6=9 for (n = 1; n <= 3; n++) { ret = ret * n; sum = sum + ret; } printf("sum=%d\n", sum); return 0; }
3. 在一个有序数组中查找具体的某个数字n。(讲解二分查找)
//查找7 #include<stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 7; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]);//求数组长度 for (i = 0; i < sz; i++) { if (k == arr[i]) { printf("找到了,下标是:%d\n", i); break; } } if (i == sz) printf("找不到\n"); return 0; }
//二分法查找算法、折半查找算法——复杂度-log以2为底的n #include<stdio.h> int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; sz=sizeof(arr) / sizeof(arr[0]); int left = 0;//左下标 int right = sz - 1;//右下标 int key = 7; int mid = 0; while (left <= right) { mid = (left + right) / 2; if (arr[mid] > key) { right = mid - 1; } else if (arr[mid] < key) { left = mid + 1; } else break; } if (left <= right) printf("找到了,下标是%d\n", mid); else printf("找不到\n"); }
4. 编写代码,演示多个字符从两
#include<stdio.h> #include<string.h> #include<windows.h> int main() { char arr1[] = "welcome to bit!!!";//未给定空间大小,不用计算 char arr2[] = "#################"; int left = 0; int right = strlen(arr1) - 1;//strlen求字符串长度 //或者sizeof(arr1) / sizeof(arr1[0])-2 //arr[]="abc"; //[a b c \0] // 0 1 2 3 //4-2 while (left<=right) { arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%s\n", arr2); Sleep(1000);//休息一秒 system("cls");//执行系统命令的一个函数-cls清空屏幕 left++; right--; } return 0; }
5. 编写代码实现,模拟用户登录情景,并且只能登录三次。(只允许输入三次密码,如果密码正确则 提示登录成,如果三次均输入错误,则退出程序
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() { int i = 0; char password[20] = { 0 }; for (i = 0; i < 3; i++) { printf("请输入密码:>"); scanf("%s", password); if (strcmp(password , "123456")==0)//库函数-strcmp //password大于字符串,返回大于0的值 //password小于字符串,返回小于0的值 //if (password == "123456") //==不能用来判断两个字符串是否相等 { printf("登陆成功\n"); break; } else { printf( "密码错误\n" ); } } if (i == 3) printf("三次密码均错误,退出程序\n"); return 0; }
6.猜数字游戏实现
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <stdlib.h>//rand #include <time.h>//time void menu()//打印菜单函数,函数无返回值 { printf("**********************************\n"); printf("*********** 1.play **********\n"); printf("*********** 0.exit **********\n"); printf("**********************************\n"); } //RAND_MAX--rand函数能返回随机数的最大值。 void game() { int random_num = rand() % 100 + 1; //rand产生一个0 - 0x7fff的随机数,最大是32767 //生成1-100 int guess = 0; while (1) { printf("请输入猜的数字>:"); scanf("%d", &guess); if (guess > random_num) { printf("猜大了\n"); } else if (guess < random_num) { printf("猜小了\n"); } else { printf("恭喜你,猜对了\n"); break; } } } int main() { int input = 0; srand((unsigned)time(NULL));//srand设置随机起点 //添加随机值,添加时间戳,设置随机数生成起点 //使用time函数,NULL空指针 //unsigned整型无符号 do//do while最少执行一次 { menu();//菜单函数 printf("请选择>:"); scanf("%d", &input);//取地址 switch (input) { case 1: game();//返回game break; case 0: printf("退出优秀\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }
四、 goto语句
用法:终止程序在某些深度嵌套的结构的处理过程
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <string.h> int main() { char input[10] = { 0 }; system("shutdown -s -t 60");//system-执行系统命令 again: printf("电脑将在1分钟内关机,如果输入:111,就取消关机!\n请输入:>"); scanf("%s", input); if (0 == strcmp(input, "我是猪"))//strcmp--比较字符串 { system("shutdown -a"); } else { goto again; } return 0; }