控制语句
控制语句即用来实现对程序流程的选择、循环、转向和返回等进行控制。
1. 分支语句
1.1if语句
1.1.1基本结构
if(表达式)
{
语句块1;
}
else
{
语句块2;
}
执行顺序:如果条件成立,则执行语句块1,否则条件不成立的话执行语句块2。
例子:
if(下雨)
{
带伞;
}
else
{
不带伞;
}
练习:输入a和b两个整数,用if语句实现两数相减
#include <stdio.h>
int main()
{
int a, b;
scanf("%d %d", &a, &b);
if (a > b)
printf("%d\n", a - b);
else
printf("%d\n", b - a);
return 0;
}
1.1.2分层结构
if(表达式1)
{
语句块1;
}
else if(表达式2)
{
语句块2;
}
else
{
语句块3;
}
执行顺序:如果满足if中的表达式则进入if后面语句块1执行,如果不满足则进入下面else if中表达式进行判断,如果条件满足则进入else if下面的语句块2执行,如果不满足继续往后执行,最后如果都不满足则进入else下面语句块3执行。
例如:
练习:从终端输入一个学生的成绩,判断学生成绩,打印成绩级别
【90 - 100】 A
【80 - 89】 B
【70 - 79】 C
【60 - 69】 D
< 60 sorry you lost
#include <stdio.h>
int main()
{
int score;
scanf("%d", &score);
if (score <= 100 && score >= 90)
printf("A\n");
else if (score <= 89 && score >= 80)
printf("B\n");
else if (score <= 79 && score >= 70)
printf("C\n");
else if (score <= 69 && score >= 60)
printf("D\n");
else if (score >= 0 && score < 60)
printf("sorry, you lost!\n");
else
printf("input err!\n");
return 0;
}
1.1.3嵌套结构
if(表达式1)
{
if(表达式2)
{
语句块1;
}
else
{
语句块2;
}
}
else
{
语句块3;
}
执行顺序:如果满足if中的表达式则进入if后面语句块1执行,如果不满足则进入下面else if中表达式进行判断,如果条件满足则进入else if下面的语句块2执行,如果不满足继续往后执行,最后如果都不满足则进入else下面语句块3执行。
例子:如果下雨就带伞,并且如果下大雨我就乘车,否则我就走路。不下雨我就不带伞了。
练习:把上题学生成绩用嵌套结构锁定在0大100范围内再判断等级,否则打印错误提示。
#include <stdio.h>
int main()
{
int score;
scanf("%d", &score);
if (score >= 0 && score <= 100)
{
if (score >= 90) //90-100
printf("A\n");
else if (score >= 80) //80-89
printf("B\n");
else if (score >= 70) //70-79
printf("C\n");
else if (score >= 60) //60-69
printf("D\n");
else if (score < 60) //0-59
printf("sorry, you lost!\n");
}
else
printf("input score err!\n");
}
总结:
(1) 首先判断表达式是否成立,如果成立就执行if下面的语句块,否则就执行else下面的语句块。
(2) if后面可以没有else,但是else前面必须有if
(3) if和else以及else if后面如果只有一行语句可以省略花括号{}
1.2switchcase语句
基本结构:
switch(变量或表达式)
{
case 常量1: 语句块1; break;
case 常量2: 语句块2; break;
case 常量3: 语句块3; break;
...
case 常量n: 语句块n; break;
default: 语句块n+1;
}
执行顺序:
当变量表达式所表达的量与其中一个case语句中的常量相符时,就执行此case语句后面的语句,并依次下去执行后面所有case语句中的语句,除非遇到break, 语句跳出switch语句为止。如果变量表达式的量与所有case语句的常量都不相符,就执行default语句中的语句。
注意:
1. 表达式不能是浮点型或字符串
2. case后面的break可以省略,但是省略时会顺序执行,直到遇到break结束;
练习:从终端输入一个学生的成绩,判断学生成绩,打印成绩级别用switch写
【90 - 100】 A
【80 - 89】 B
【70 - 79】 C
【60 - 69】 D
< 60 sorry you lost
#include <stdio.h>
int main()
{
int score;
scanf("%d", &score);
switch (score / 10)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
printf("you got lost!!!\n");
break;
case 6:
printf("D\n");
break;
case 7:
printf("C\n");
break;
case 8:
printf("B\n");
break;
case 9:
case 10:
printf("A\n");
break;
default:
printf("err!!!\n");
break;
}
}
练习:从终端输入一个日期
scanf ("%d %d %d ", &year , &mon , &day ),判断这是这一年的第几天
(提示:判断闰年还是平年,闰年且闰年二月份以上比平年多一天。普通年份除以4,有余数是平年,对于整百的年份,比如2100年,要除以400,有余数就是平年,整除就是闰年。)
例如:
20240718
flag=判断是否闰年
31+(28 + flag) + 31 + 30 + 31 + 30 + 18=
(135781012(31天))
方法一:
#include <stdio.h>
int main()
{
int year, month, day, days = 0, flag = 0;
scanf("%d %d %d", &year, &month, &day);
if (year % 100 == 0) //整百年,能被100整除
{
if (year % 400 == 0)
flag = 1; //闰年
else
flag = 0; //平年
}
else //不能被100整除, 非整百年
{
if (year % 4 == 0) //能被4整除,闰年
flag = 1;
else
flag = 0; //不能被4整除,平年
}
//flag = (year % 100 != 0 && year % 4 == 0) || (year % 400 == 0);
switch (month)
{
case 1:
days = day;
break;
case 2:
days = 31 + day;
break;
case 3:
days = 31 + 28 + flag + day;
break;
case 4:
days = 31 + 28 + flag + 31 + day;
break;
case 5:
days = 31 + 28 + flag + 31 + 30 + day;
break;
case 6:
days = 31 + 28 + flag + 31 + 30 + 31 + day;
break;
case 7:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + day;
break;
case 8:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + 31 + day;
break;
case 9:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + 31 + 31 + day;
break;
case 10:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
break;
case 11:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
break;
case 12:
days = 31 + 28 + flag + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
break;
default:
printf("month err\n");
return -1; //return 0代表正常退出,非0代表有异常退出
}
printf("这是这一年的第 %d 天\n", days);
return 0;
}
方法二:利用累加
#include <stdio.h>
int main()
{
int year, month, day, days = 0, flag = 0;
scanf("%d %d %d", &year, &month, &day);
if (year % 100 == 0) //整百年,能被100整除
{
if (year % 400 == 0)
flag = 1; //闰年
else
flag = 0; //平年
}
else //不能被100整除, 非整百年
{
if (year % 4 == 0) //能被4整除,闰年
flag = 1;
else
flag = 0; //不能被4整除,平年
}
//flag = (year % 100 != 0 && year % 4 == 0) || (year % 400 == 0);
switch (month)
{
case 12:
days += 30; //days= days +30;
case 11:
days += 31;
case 10:
days += 30;
case 9:
days += 31;
case 8:
days += 31;
case 7:
days += 30;
case 6:
days += 31;
case 5:
days += 30;
case 4:
days += 31;
case 3:
days += 28 + flag;
case 2:
days += 31;
case 1:
days += 0;
break;
default:
printf("month err\n");
return -1; //return 0代表正常退出,非0代表有异常退出
}
days = days + day;
printf("这是这一年的第 %d 天\n", days);
return 0;
}
总结:
(1) 执行顺序:先判断switch()中的条件是否满足以下的case,如果满足则执行满足的case中的语句块,如果都不满足则执行default中的默认语句块。
(2) 如果case的语句块和下面case中的语句块相同,则可以省略。形式如下:
case 常量1:
case 常量2:语句块1;break;
遵守switch语句规则
switch语句非常有用,但在使用时必须谨慎。所写的任何switch语句都必须遵循以下规则:
(1)只能针对基本数据类型中的整型类型使用switch,这些类型包括int、char等。对于其他类型,则必须使用if语句。
(2)case标签必须是常量表达式(constantExpression),如42或者'4'。
(3)case标签必须是唯一性的表达式;也就是说,不允许两个case具有相同的值。
2. 循环语句
2.1for循环
2.1.1基本结构
格式:
for(表达式1;表达式2;表达式3)
{
语句块;
}
表达式1:赋初值
表达式2:判断的判断条件
表达式3:增值或减值
执行顺序:
首先执行表达式1进行赋值,然后判断表达式2是否成立,如果成立就进入循环执行语句块,再执行表达式3进行增值或减值然后继续判断表达式2是否成立,直到表达式2不成立退出循环。
例子:打印1到5
#include <stdio.h>
int main()
{
for (int i = 1; i <= 5; i++)
{
printf("%d\n", i);
}
return 0;
}
练习:1到10求和
#include <stdio.h>
int main()
{
int a=0;
for (int i = 1; i <= 10; i++) //i=11
{
a += i; //a=a+i; //a=55
printf("%d\n", a); //1+2+..+10 =55
}
return 0;
}
2.1.2嵌套结构
格式:
for(表达式1;表达式2;表达式3)
{
for(表达式4;表达式5;表达式6)
{
语句块;
}
}
练习:用for循环打印99乘法表
i=1: 1*1=1(j<=i)
i=2: 1*2=2 2*2=4(j<=i)
i=3: 1*3=3 2*3=6 3*3=9(j<=i)
i=4: 1*4=4 2*4=8 3*4=12 4*4=16
i=5: 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
i=6: 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
i=7: 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
i=8: 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
i=9: 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
#include <stdio.h>
int main()
{
int i, j;
for (i = 1; i < 10; i++) //循环行数
{
for (j = 1; j <= i; j++) //循环列数
printf("%d * %d = %d\t", j, i, j * i); //行和列相乘
printf("\n"); //换行
}
return 0;
}
2.1.3变形
变形一:
int i=0;
for(;表达式2;表达式3)
{
语句块;
}
变形二:
int i=0;
for(;表达式2;)
{
语句块;
表达式3;
}
变形三:
int i=0;
for(;;)//死循环
{
if(表达式2)
{
语句块;
表达式3;
}
else
{
break; //结束循环
}
}
练习:打印所有的水仙花数,
水仙花数:一个三位数,百位立方+十位立方+个位立方 = 原数
(三位数:100-999)
练习.打印以下图案:
要求行数从终端输入。
输入:5
输出以下:
#include <stdio.h>
int main()
{
int a, i, j;
scanf("%d", &a);
for (i = 1; i <= a; i++)
{
for (j = 1; j <= i; j++)
printf("*");
printf("\n");
}
return 0;
}
然后实现:
要求行数从终端输入。
输入:5
输出以下:
解题思路:
用for循环嵌套实现外层循环控制行数,内层循环控制每行个数。
图案下面倒着的部分的规律:n=5
行数i | 空格数=i-1 | 星星数=5-i+1 |
1 | 0 | 5=5-1+1 |
2 | 1 | 4=5-2+1 |
3 | 2 | 3=5-3+1 |
4 | 3 | 2=5-4+1 |
5 | 4 | 1=5-5+1 |
空格数可以:1到i-1循环
星星数可以:1到5-i+1
#include <stdio.h>
int main()
{
int n, i, j;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++)
printf("*");
printf("\n");
}
for (i = 1; i <= n; i++) //循环行数
{
for (j = 1; j <= i - 1; j++) //每一行先打印空格
printf(" ");
for (j = 1; j <= n - i + 1; j++) //每行打印星星
printf("*");
printf("\n");
}
return 0;
}
2.1.3 变形
变形一:
int i=0;
for(;表达式2;表达式3)
{
语句块;
}
变形二:
int i=0;
for(;表达式2;)
{
语句块;
表达式3;
}
变形三:
int i=0;
for(;;)//死循环
{
if(表达式2)
{
语句块;
表达式3;
}
else
{
break; //结束循环
}
}
练习:打印所有的水仙花数,
水仙花数:一个三位数,百位立方+十位立方+个位立方 = 原数
(三位数:100-999)
练习.打印以下图案:
要求行数从终端输入。
输入:5
输出以下:
#include <stdio.h>
int main()
{
int a, i, j;
scanf("%d", &a);
for (i = 1; i <= a; i++)
{
for (j = 1; j <= i; j++)
printf("*");
printf("\n");
}
return 0;
}
然后实现:
要求行数从终端输入。
输入:5
输出以下:
解题思路:
用for循环嵌套实现外层循环控制行数,内层循环控制每行个数。
图案下面倒着的部分的规律:n=5
行数i | 空格数=i-1 | 星星数=5-i+1 |
1 | 0 | 5=5-1+1 |
2 | 1 | 4=5-2+1 |
3 | 2 | 3=5-3+1 |
4 | 3 | 2=5-4+1 |
5 | 4 | 1=5-5+1 |
空格数可以:1到i-1循环
星星数可以:1到 5-i+1
#include <stdio.h>
int main()
{
int n, i, j;
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++)
printf("*");
printf("\n");
}
for (i = 1; i <= n; i++) //循环行数
{
for (j = 1; j <= i - 1; j++) //每一行先打印空格
printf(" ");
for (j = 1; j <= n - i + 1; j++) //每行打印星星
printf("*");
printf("\n");
}
return 0;
}
2.2 while循环
格式:
定义循环变量并赋值;
while(判断条件)
{
语句块;
增值或减值语句;
}
执行顺序:
首先定义循环变量并赋值,然后判断条件是否符合,如果符合就进入循环执行语句块及增值减值语句,然后继续判断,直到不成立退出循环。
相当于for循环的第二个变形。
练习:输入任意两个数,输出两数之间(包括这两个数)偶数之和。
思路:将输入的两个数a,b中小的数a,依次加1,加到b的值,
每次循环判断这个数a是否为偶数,是则累加到sum中
#include <stdio.h>
int main()
{
int a, b, sum = 0;
int temp;
scanf("%d%d", &a, &b); //a=12 b=10
if (a > b)
{
temp = a; //temp=a=12
a = b; //a=b=10
b = temp; //b=temp=12
}
for (int i = a; i <= b; i++) //i=a=10 , 10<=12// i=i+1=11, 11<=12 //i=i+1==12 ,12<=12 //i=i+1=13 ,13<=12不满足
{
if (i % 2 == 0) //10%2==0 //11%2==0 //12%2==0
sum += i; //sum=sum+i; //sum=sum+i =0+10=10 //sum=10+12=22
}
printf("sum=%d\n", sum); //22
return 0;
}
3. 预习while循环,用while实现1到10求和
#include <stdio.h>
int main()
{
int sum = 0;
int i = 1;
while (i <= 10)
{
sum += i;
i++;
}
printf("%d\n", sum);
return 0;
}
2.3 do while
格式:
赋初值语句;
do
{
语句块;
增减值语句;
}while(判断条件);
执行顺序:先执行后判断
例如:实现1-10求和
#include <stdio.h>
int main()
{
int sum = 0;
int i = 1;
do
{
sum += i;
i++;
} while (i <= 10);
printf("sum =%d\n", sum);
return 0;
}
左边do-while右边while
两者区别:
1. 执行顺序不同:do while先执行后判断,while先判断后执行。
2. 执行次数不同:do while至少会执行一次。
2.5 死循环
for(;;){}
while(1){};
while(1);
2.6 循环控制语句
break continue goto
(1) break: 直接结束循环
(2) continue: 结束本次循环,继续下一次循环
(3) goto: 强制跳转到标签位置,可以应用于多重循环嵌套。(尽量不要使用!)
例如:
for()
{
for()
{
for()
{
if(错误条件)
goto error;
}
}
}
...
error:
...//处理错误的情况
练习:打印100到200中能被三整除的数
#include <stdio.h>
int main()
{
int a;
for (a = 100; a <= 200; a++)
{
if (a % 3 != 0) //只要不能被3整除就跳过不打印,进行下一次循环
continue;
printf("%d\n", a);
}
return 0;
}
练习:从终端上循环输入一个字符并在终端上输出这个字符,当输入字符为‘q’时,程序结束。
#include <stdio.h>
int main()
{
char ch;
while (1)
{
scanf(" %c", &ch); //注意垃圾字符回收问题
if (ch == 'q')
break;
printf("%c\n", ch);
}
return 0;
}
使用场景:
使用在循环语句中,结束循环
使用时需要有判断条件
练习:循环输入一个5位数,判断它是不是回文数。当输入0时循环结束,是回文数循环也结束。
即12321是回文数,个位与万位相同,十位与千位相同。
#include <stdio.h>
int main()
{
int n, g, s, q, w;
for (;;)
{
scanf("%d", &n);
g = n % 10;
s = n / 10 % 10;
q = n / 1000 % 10;
w = n / 10000;
if (n == 0 || (g == w && q == s))
break;
else
printf("%d\n", n);
}
return 0;
}