一、选择结构
if语句
-
if单分支语法结构
-
if双分支语法结构
-
if多分支语法结构
switch语句(多分支语句)
嵌套语句
-
a. if-else嵌套
-
b. switch嵌套
if语句
1. if单分支语法结构
if (表达式){
语句;
}
举例:
int a = 10;
int b = 20;
if (a < b) {
printf("a is less than b.\n");
}
2. if双分支语法结构
if (表达式){
语句1;
}
else{
语句2;
}
举例:
int score = 75;
if (score > 70) {
printf("Pass\n");
} else {
printf("Fail\n");
}
- 最好加代码块{ },若不加代码块则默认只执行if语句后面一条语句
- else与它最近的if相匹配
- 其中表达式:
- A) 必须是逻辑表达式
- B) 必须是关系表达式
- C) 必须是逻辑表达式或关系表达式
- D) 可以是任意合法的表达式`
解释:if
语句中的“表达式”可以是任意合法的表达式,意味着它可以是逻辑表达式、关系表达式,或者是任何其他能够产生一个可以被解释为布尔值(真或假)的表达式。
在计算时,如果结果为非零值(真),则会执行if
语句中的代码块;如果结果为零(假),则跳过if
语句中的代码块。
以下是一些合法的if
语句中的“表达式”:
- 逻辑表达式:
if(a && b)
- 关系表达式:
if(a > b)
- 算术表达式:
if(a + b)
- 单值表达式:
if(a)
(这里a
可以是任何值,如果a
非零,则为真)
C语言中,任何非零值都被视为真,而零值被视为假。因此,if
语句中的表达式可以非常灵活,不仅限于逻辑或关系表达式。
3. if多分支语法结构
if (表达式 1)
{ 语句 1 ; }
else if (表达式2)
{ 语句 2 ; }
else if (表达式3)
{ 语句3 ; }
else
{ 语句4 ; }
举例1:成绩分类
int score = 85;
if (score >= 90) {
printf("A\n");
} else if (score >= 80) {
printf("B\n");
} else if (score >= 70) {
printf("C\n");
} else {
printf("D or F\n");
}
举例2:检查年龄范围
int age = 25;
if (age < 13) {
printf("Child\n");
} else if (age < 20) {
printf("Teenager\n");
} else if (age < 65) {
printf("Adult\n");
} else {
printf("Senior Citizen\n");
}
举例3:判断闰年
int year = 2024;
if (year % 4 != 0) {
printf("%d is not a leap year.\n", year);
} else if (year % 100 != 0) {
printf("%d is a leap year.\n", year);
} else if (year % 400 != 0) {
printf("%d is not a leap year.\n", year);
} else {
printf("%d is a leap year.\n", year);
}
举例4:温度范围
float temperature = 36.5;
if (temperature < 35.0) {
printf("Below normal body temperature.\n");
} else if (temperature < 37.5) {
printf("Normal body temperature.\n");
} else if (temperature < 38.5) {
printf("Above normal body temperature.\n");
} else {
printf("Fever detected.\n");
}
举例5:用户输入验证
char input;
printf("Enter 'A' for apple or 'B' for banana: ");
scanf(" %c", &input); // 注意前面的空格,用于消耗前面的换行符
if (input == 'A') {
printf("Chosen: Apple\n");
} else if (input == 'B') {
printf("Chosen: Banana\n");
} else {
printf("Invalid input.\n");
}
举例6:检查文件状态
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("Error opening file");
} else if (fscanf(file, "%d", &number) != 1) {
fprintf(stderr, "Error reading number from file.\n");
} else {
printf("Number read from file: %d\n", number);
}
fclose(file);
- 如果 表达式 的结果为真,则语句执行。 0表示假,非0表示真
switch(多分支语句)语法结构:**
常应用于多分支的情况
switch语法结构:
switch (整型表达式)
{
case 整形常量表达式 :
语句1 ;
break ;
case 整形常量表达式 :
语句2 ;
break ;
default :
语句n;
break ;
}
举例1:
int month = 3;
switch (month) {
case 1:
printf("January\n");
break;
case 2:
printf("February\n");
break;
default:
printf("Not a valid month\n");
break;
}
举例2:switch
语句处理数值范围
int score = 85;
switch (score / 10) {
case 9:
case 10:
printf("A\n");
break;
case 8:
printf("B\n");
break;
case 7:
printf("C\n");
break;
case 6:
printf("D\n");
break;
default:
printf("F\n");
break;
}
- 若不加break,则会向下执行后面的语句,直到遇见break
- 每个 switch 语句中只能出现 一条 default 子句。 但是它可以出现在语句列表的任何位置
嵌套语句
switch语句和if-else语句都可以嵌套使用
- if-else嵌套语法结构
if (表达式)
{
if (表达式)
{
语句;
}
else if (表达式)
{
语句;
}
else
{
语句;
}
}
else
{
语句;
}
if (表达式) {
if (表达式)
{
语句;
}
else
{
语句;
}
举例:
#include <stdio.h>
int main() {
int x = 10;
int y = 5;
// 外层if-else结构
if (x > y) {
// x大于y的情况
if (x > 10) {
// x不仅大于y,还大于10
printf("x is greater than y and also greater than 10.\n");
} else {
// x大于y,但不大于10
printf("x is greater than y but not greater than 10.\n");
}
} else {
// x不大于y的情况
printf("x is not greater than y.\n");
}
// 另一个独立的if-else结构
if (y < 10) {
// y小于10
printf("y is less than 10.\n");
} else {
// y不小于10
printf("y is not less than 10.\n");
}
return 0;
}
说明:首先检查变量x
是否大于变量y
。如果是,进一步检查x
是否还大于10。根据这些条件,打印出相应的消息。如果x
不大于y
,打印出x
不大于y
的消息。
然后,用一个独立的if-else
结构来检查变量y
是否小于10,并打印相应的消息。
请注意,第二个if-else
结构是独立的,它不属于第一个if-else
结构的内层。如果需要将第二个if-else
结构作为第一个结构的内层,你需要将它放在第一个if-else
结构的花括号内部。但第二个if-else
结构是与第一个并列的,而不是嵌套的。
- switch嵌套语法结构
switch (整形表达式)
{
case 整形常量表达式:
语句;
break;
case ?:
语句;
switch (整形表达式)
{
case 整形常量表达式:
语句;
break;
default:
语句;
break;
}
break;
default:
break;
}
举例:
#include <stdio.h>
int main() {
int month = 3;
int day = 14;
switch (month) {
case 1:
case 2:
case 11:
case 12:
printf("These months have 31 days.\n");
break;
case 4:
case 6:
case 9:
case 11:
printf("These months have 30 days.\n");
break;
case 3:
case 5:
case 7:
case 8:
printf("Switching to another switch for February.\n");
// 开始嵌套的 switch 语句
switch (day) {
case 14:
printf("Valentine's Day is on February 14th.\n");
break;
case 29:
printf("Leap year detected!\n");
break;
default:
printf("February has 28 or 29 days.\n");
break;
}
break;
default:
printf("Invalid month.\n");
break;
}
return 0;
}
说明:在这个例子中,外层的 switch
语句根据 month
变量的值来决定执行哪个 case
。当 month
为 3(即三月)时,程序会打印一条消息,然后进入内层的 switch
语句。内层的 switch
语句根据 day
变量的值来决定执行哪个 case
。例如,如果 day
为 14,程序会打印情人节的消息。
请注意,内层 switch
语句的 default
部分是可选的,就像外层 switch
语句的 default
部分一样。如果某个 case
匹配成功,执行完相应的语句后,break
语句会跳出当前的 switch
结构。如果没有找到匹配的 case
,并且没有 default
部分,程序会继续执行下一个 switch
结构中的代码,直到遇到 break
语句或者到达 switch
结构的末尾。
二、三大循环语句
(1)while语句
while 语句的语法结构和 if 语句⾮常相似。
注意:结构中会包含三大要素:初值、条件、增量
while(表达式)
{
语句;
}
在这个结构中,while通过判断表达式的真假来执行语句,这里的语句就是循环体, 循环体呢可以是一个语句,也可以是复合语句({}括起来的语句),执行循环体的次数是由循环条件控制的,这个循环条件就是表达式,它也称为循环条件表达式,当值为非0就执行循环体,当值为0就不执行循环体。
while语句特点,先判断表达式,再执行循环体语句。while语句可简单记为:只要循环条件表达式为真,就执行循环体语句。
- 举例:求1+2+3+…+100的和
#include<stdio.h>
int main()
{
int i = 1,sum = 0; //初值
while(i<=100) //条件
{
sum += i;
i++; //增量
}
printf("%d",sum);
return 0;
}
说明:
(1)如果循环体是复合语句要用花括号括起来,如果没有花括号则和if语句配对类似,都只选择最近的一个语句为循环体语句。
(2)while先判断i是否小于等于100,如果是则执行sum+=i,i++,如果不是则执行printf语句。
(3)不要忽略给i或者sum赋值,如果不赋值则系统会自动赋值,从而导致程序结果错乱。
(4)在循环体中最好有一个让循环趋于结束的语句,否则循环会进入死循环,死循环就是无限执行循环体 ,在该例子中循环体用了i++让循环表达式有一个判断真假的情况。
- if和while的类比
#include <stdio.h>
int main()
{
if(1)
printf("hello world\n"); //if后边条件满⾜,打印⼀次hello world
return 0;
}
include <stdio.h>
int main()
{
while(1)
printf("hello world\n"); //while后边的条件满⾜,死循环的打印hello world
return 0;
}
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
while(n)
{
printf("%d ", n%10);
n / = 10;
}
return 0;
}
程序分析:该程序主要考察%和/的用法,如果想得到一个整数的最低为就让它%10,如果想去掉它就用/10。
(2)do…while语句
do
{
语句;
}
while(表达式);
在 do while 循环中先执⾏“语句”,执⾏完语句,在去执⾏“判断表达式”,判断表达式的 结果是!=0,则继续循环,执⾏循环语句;判断表达式的结果为0,则循环结束。 所以在 do while 语句中循环体是⾄少执⾏⼀次的,这是 do while 循环⽐较特殊的地⽅。
do…while语句的特点:先无条件执行循环体,然后判断循环条件是否成立。
- 举例:求1+2+3+…+100的和
#include<stdio.h>
int main()
{
int i = 1, sum = 0;
do
{
sum += i;
i++;
} while (i <= 100);
printf("%d", sum);
return 0;
}
我们可以看到两个程序无论是while和do…while的结果都一样,但二者存在一定区别。其次do…while中while后有个分号不能遗漏了**
(3)for语句
for语句的形式如下
for(表达式1(初值):表达式2(条件):表达式3(增量)
{
语句;
}
//但其实它和while语句等价
表达式1;
while(表达式2)
{
语句;
表达式3;
}
先求解表达式1然后到表达式2判断条件,为真就执行语句,然后到表达式3,然后继续执行表达式1,接着判断表达式2,要是假直接出循环。
for循环注意的点:
-
(1)表达式1可以省略但后面的分号不能省略,例如:for(;i<=100;i++)
-
(2)表达式2如果省略即认为该循环为死循环
(4)循环的嵌套
到这里,你已经知道了上述三种循环 while , do while , for ,这三种循环往往会嵌套在⼀起才能更好的解决问题
举例:求100~200的素数
#include<stdio.h>
#include<math.h> //数学库,用于后面的开方运算
int main() //程序入口
{
int n = 0, k = 0, i = 0, m = 0; //定义变量
//这个循环从101开始,逐个检查每个奇数,直到200。每次循环`n`增加2,确保只检查奇数
for (n = 101; n <= 200; n += 2)
{
k = sqrt(n); //使用`math.h`库中的`sqrt`函数计算当前奇数`n`的平方根,存储在变量`k`中
for (i = 2; i <= k; i++)
{
if (n % i == 0)
break;
}
if (i >= k + 1)
{
printf("%d\t", n);
}
m = m + 1;
if (m % 10 == 0)
printf("\n");
}
printf("\n");
return 0;
}
说明:
- 定义了四个整型变量,分别用于:
- n:存储当前检查的奇数。
- k:存储
n
的平方根。 - i:用于内层循环,检查
n
是否有除了1和它自身之外的因数。 - m:用于计数,每打印10个素数就换行。
-
内层循环:
for (i = 2; i <= k; i++)
这个循环从2开始,检查
n
是否有除了1和它自身之外的因数。如果n
不是素数,那么它必定有一个因数不大于它的平方根。 -
检查因数:
if (n % i == 0)
如果
n
能被i
整除(即余数为0),则n
不是素数,内层循环通过break
语句提前结束。 -
判断素数:
if (i >= k + 1)
如果内层循环正常结束(即没有找到因数),则
i
的值会大于k
(k
的值是n
的平方根),这时n
是一个素数。 -
打印素数:
printf("%d\t", n);
如果
n
是素数,就打印出来,后面跟一个制表符(\t
)用于分隔。 -
计数并换行:
m = m + 1; if (m % 10 == 0) printf("\n");
每打印一个素数,
m
就加1。当m
是10的倍数时,意味着已经打印了10个素数,此时打印一个换行符,以便下一行继续打印。
整个程序通过两层循环嵌套,外层循环控制检查的数,内层循环用于判断这个数是否为素数。如果一个数是素数,它将被打印出来,每打印10个素数,输出会自动换行,以便于阅读。
循环注意的点:
1.在while和do…while循环中,只在while后面的括号内指定循环条件,为了使循环结束,应在循环体中包含能使循环结束的语句。而在for循环中应该在表达式3中包含。
2.用while和do…while循环时,循环变量的初始化应该在while或者do…while语句之前,而for循环可以在表达式1,但还是最好要在for语句之前。
三、循环结构中break和continue语句的使用
在循环执⾏的过程中,如果某些状况发⽣的时候,需要提前终⽌循环,这是⾮常常用的操作。这时候我们会使用 break 和 continue 两个关键字,下面来介绍它们的作用
break语句的介绍
break语句不仅可以流程跳出switch结构,继续执行switch语句后的内容,还可以让流程跳出循环体,即提前跳出循环体。
switch(整形表达式)
{
case 整型常量表达式:
break;
}
while()
{
语句;
break;
}
for()
{
语句;
break;
}
break语句的一般形式就是break;它的作用就是让流程跳出循环体之外,结束本次循环。
while语句中的break
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
break;
printf("%d", i);
i++;
}
return 0;
}
说明:
这段代码将打印从1到4的整数,当i
等于5时,break
语句将终止循环,因此数字5不会被打印。程序随后结束,返回值为0。
举例:使用while
循环和计数器来控制重复执行的次数
#include <stdio.h>
int main() {
int count = 0; // 初始化计数器
while (count < 5) { // 当计数器小于5时循环继续
printf("Hello, World!\n"); // 打印 "Hello, World!" 和换行符
count++; // 每次循环后计数器递增
}
return 0; // 程序结束,返回0
}
最后,我们可以得到结论,如果遇到break语句,这个循环体就不执行啦,这个循环也结束了,
那如果是continue呢?
while语句中的continue
#include<stdio.h>
int main()
{
int i = 1;
while (i <= 10)
{
if (i == 5)
continue;
printf("%d", i);
i++;
}
return 0;
}
奇怪的是这次没有出现按任意键继续了,为什么呢?
因为这里是进入了死循环,当i=5的时候,后面i++语句没有执行,然后返回循环,接着判断,然后又不执行i++语句,就相当于当i=5的时候,循环结束的条件就不存在了,所以一直循环。
可以对比上面的代码:
int main()
{
int i=1;
while (i <= 10)
{
i++;
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
至此break和continue的区别在while中你应该非常清楚啦,那么基于此,在for循环中又会出现什么新花样呢?
for循环里的break语句
#include<stdio.h>
int main()
{
int i=1;
for(i=1;i<=10;i++)
{
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
结果和while中没有太大区别,一遇到break,循环就结束了。
for循环中的continue语句
#include<stdio.h>
int main()
{
int i=1;
for(i=1;i<=10;i++)
{
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
那么虽然continue不执行后面的printf代码了,但是仍然执行i++语句,也就是说for和while最大的区别就在于此,continue不会影响for()中的表达式。
在do…while中的break
int main()
{
int i=1;
while (i <= 10)
{
i++;
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
在do…while语句中,循环会先执行一次然后判断条件,所以第一次就先打印了2,最后5打印完的时候,执行到break语句循环就结束了
do…while语句中的continue
#include<stdio.h>
int main()
{
int i = 1;
do
{
if (i == 5)
continue;
i++;
printf("%d ", i);
} while (i<=10);
return 0;
}
思考:上面的代码是否会陷入死循环?
最后我来总结一下
-
break 的作⽤是⽤于永久的终⽌循环,只要 break 被执⾏,直接就会跳出循环,继续往后执⾏。一句话:结束本次循环
-
continue 的作⽤是跳过本次循环 continue 后边的代码,在 for 循环和 while 循环中有所差异的。一句话:结束当前循环