C语言分支和循环语句
语句的分类
条件判断语句(分支语句):
if语句,switch语句
循环执行语句:
do-while语句,while语句,for语句
转向语句:
break语句,goto语句,continue语句,return语句
if语句
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int age = 10;
scanf("%d", &age);
if (age < 18)
{
printf("青少年\n");
}
else if (age >= 18 && age <= 28)
{
printf("青年\n");
}
else if (age > 28 && age <= 50)
{
printf("中年\n");
}
else
{
printf("老年\n");
}
return 0;
}
样例输入:45
输出:中年
注:
如果if内只有一个语句{}可以省略,多个语句则要加上{}
if语句条件判断的小细节
int a = 5;
//以下两种方法都可以
if (5 == a)
// 此方法便于提示,若不小心写成一个=,则会报错
if (a == 5)
// 此方法,若省略一个=,则不会报错
练习:
输出1~100之间的奇数:
第一种:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0;
while (a <= 100)
{
if (a % 2 == 1)
{
printf("%d\n", a);
}
a++;
}
return 0;
}
第二种:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 1;
while (a <= 100)
{
printf("%d\n", a);
a+=2;
}
return 0;
}
break语句
例题1:
按要求输出星期
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int day;
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;
}
例题2:
输入1~5, 输出weekday
输入6~7,输出weekend
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int day;
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("输入错误\n");
break;
}
return 0;
}
循环语句
for
执行完循环体之后再去执行表达式3
若判断部分省略,意味着这个判断恒成立
嵌套理解:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0, j = 0;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++)
{
printf("hh\n");
}
}
return 0;
}
i=0进入循环,j=0依次到j=10跳出内for循环,
然后i=1再次进入内for循环
省略的弊端:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0, j = 0;
for (; i < 3; i++)
{
for (; j < 3; j++)
//没有初始化,j=3跳出循环后,再次进入循环,j=3不能进入循环了
{
printf("hh\n");
}
}
return 0;
}
打印三次hh
试着判断以下代码循环几次【狗头】
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
{
k++;
}
return 0;
}
答案是 0次,因为k=0不是判断,不进入循环
while
打印输出1~10
int main()
{
int i = 1;
while (i <= 10)
{
printf("%d\n", i);
i++;
}
return 0;
}
break用法
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (5 == i)
{
break;
}
printf("%d\n", i);
i++;
}
return 0;
}
打印输出1~4,i==5时直接终止运行
continue用法
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (5 == i)
continue; // 跳过此循环,进行下次循环
printf("%d\n", i);
i++;
}
return 0;
}
该代码进行死循环
若把i++提前
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
i++;
if (5 == i)
continue;
printf("%d\n", i);
}
return 0;
}
输出
2
3
4
6
7
8
9
10
11
getchar() putchar()
获取一个字符
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int ch = getchar();
printf("%c\n", ch); // 第一种方法输出
putchar(ch); // 第二种方法输出
return 0;
}
样例输入输出:
w
w
w
scanf读取的实质
scanf()不能读取空格
char password[20]={0};
scanf("%s",password);
printf("%s",password);
输入:sada aad
输出:sada
输入的时候按回车,在缓冲区内会有\n字符
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码->");
scanf("%s", password);
printf("请确认密码Y\N->");
int ret = getchar();
if ('Y' == ret)
{
printf("Yes");
}
else
{
printf("No");
}
return 0;
}
直接输出No
原因
输入时,按回车,缓冲区内有asd\n,password只存储了asd,\n被getchar()获取,ret=\n,所以输出No
为了避免这种情况,同时避免scanf无法获取空格,可以再次利用getchar(),把其字符获取,消除
加上while(getchar())
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char password[20] = { 0 };
printf("请输入密码->");
scanf("%s", password);
int ch = 0;
while (ch = getchar() != '\n')
{
;
}
printf("请确认密码Y\N->");
int ret = getchar();
if ('Y' == ret)
{
printf("Yes");
}
else
{
printf("No");
}
return 0;
}
只获取数字字符
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
char ch = '\0';
while ((ch = getchar()) != EOF)
{
if (ch < '0' || ch>'9')
{
continue;
}
putchar(ch);
}
return 0;
}
do while
至少要循环一次哦,但使用场景有限,比较少用
例题解析:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 1;
do
{
i++;
if (5 == i)
{
break;
// 跳出循环,下面不再执行
}
printf("%d", i);
}
while (i <= 10);
return 0;
}
打印 234
把break换成continue,会打印出什么结果呢?
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 1;
do
{
i++;
if (5 == i)
{
continue;
}
printf("%d", i);
}
while (i <= 10);
return 0;
}
打印1~11,没有5
例题
1 求1!+2!+…+10!
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0,n = 0;
int ret = 1,s = 0;
for (n=1;n<=10;n++)
{
for (ret=1,i= 1;i<= n; i++)
{
ret = ret * i;
}
s += ret;
}
printf("%d", s);
return 0;
}
此方法用了两层for循环,效率不高,对此优化后为:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0,n = 0;
int ret = 1,s = 0;
for (n=1;n<=10;n++)
{
ret = ret * i;
s += ret;
}
printf("%d", s);
return 0;
}
2 字符串逐渐输出
样例:
#########
w#######!
we#####x!
wes###ex!
wesx#aex!
wesxraex!
最后输出全部字符
注意的点
int arr1[] = "abc";
// “a,b,c,\0” 4个
*计算元素个数时的点 *
#include <stdio.h>
int main()
{
int arr1[] = "abc";
// “a,b,c,\0” 4个
int c = strlen(arr1) - 1; // c下标
// strlen()计算的值为3
int c = sizeof(arr1) / sizeof(arr1[0]) - 2; // c下标
// 这种方法算上了\0,这个元素
return 0;
}
最终代码如下:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
// 调用Sleep函数
int main()
{
char arr1[] = "welcom to bit!!!";
char arr2[] = "################";
int left = 0;
int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000);
// 控制语句输出时间的函数,1000意为1000ms(1s)
left++;
right--;
}
return 0;
}
输出结果:
w##############!
we############!!
wel##########!!!
welc########t!!!
welco######it!!!
welcom####bit!!!
welcom ## bit!!!
welcom to bit!!!
若想让语句输出在一行(每次输出前清空语句)
使用system(“cls”)
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int main()
{
char arr1[] = "welcom to bit!!!";
char arr2[] = "################";
int left = 0;
int right = sizeof(arr1) / sizeof(arr1[0]) - 2;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000);
//清空屏幕
system("cls");
// system是个库函数,可以执行系统命令
left++;
right--;
}
return 0;
}
3 模拟用户登录(判断两个字符串是否相等,用strcmp函数)
题目:如果用户登录三次,还是错误则退出系统
strcmp函数返回值为0时,则两个字符串相等
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0;
char password[] = { 0 };
for (i = 0; i < 3; i++)
{
printf("请输入密码:");
scanf("%s", password);
if (strcmp(password, "abcd") == 0)
{
printf("登录成功!\n");
break;
}
else
{
printf("密码错误!!!\n");
}
}
if (3 == i)
{
printf("退出程序\n");
}
return 0;
}
4 出生日期输入输出
题目:输入只有一行,例如:20020927
输出:
year = 2002
month = 09
date = 27
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int year = 0;
int month = 0;
int date = 0;
scanf("%4d%2d%2d", &year, &month, &date);
// %4d 四位字符为year
printf("year = %d\n", year);
printf("month = %02d\n", month);
// %02d 输出有两位,未满两位的前面用0补齐
printf("date = %02d\n", date);
return 0;
}
5 猜数字游戏
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void menu()
// 初始化界面
{
printf("***********************\n");
printf("******* 1.play ******\n");
printf("******* 0.exit ******\n");
printf("***********************\n");
}
void game()
// 游戏操作
{
int guess = 0;
// 生成随机数 1~100
int ret = rand() % 100 + 1;
// rand() 范围:0~rand_max(32767)
// 猜数字
while (1)
{
printf("请猜数字:>\n");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\n");
}
else
{
printf("猜对咯!!!\n");
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
// 使用time函数返回的时间戳,作为srand的起点
do
{
menu();
printf("请选择:>\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有误!!!\n");
break;
}
} while (input);
// input ---
return 0;
}
二分查找(折半查找)
条件:数值是有序的
举例,找出数组1~10,值为7的下标值
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid]> k)
{
right = mid - 1;
}
else
{
printf("找到了,下标为%d", mid);
break;
}
}
if (left > right)
{
printf("找不到");
}
return 0;
}
goto语句
从理论上来说,goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码
但是某种场合goto语句还是用的着的,最常见的用法就是终止程序在某种深度嵌套的结构的处理过程;
例如:一次跳出两层或者多层循环
多层循环这种情况,break是无法达到目的的,它只能从最内层循环退出到上一层的循环
不能跨函数
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
again:
printf("haha");
goto again;
// 死循环,跳到again
return 0;
}
正确用法:
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
for (...)
{
for (...)
{
for (...)
{
goto diss;
// 直接跳出多层循环
}
}
}
diss:
return 0;
}
搞怪,电脑关机
电脑将在60s内关机
若输入:我是猪
将取消关机
# define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
// system 函数
int main()
{
char input[] = { 0 };
system("shutdown -s -t -60");
again:
printf("注意!!!电脑将在60s内关机,若输入:我是猪,则关机取消");
scanf("%s", input);
if (strcmp(input, "我是猪") == 0)
{
system("shutdown -a");
}
else
{
goto again;
}
return 0;
}