- 当谈到C语言编程时,分支和循环语句是最基本和常用的语法结构之一。它们允许我们根据条件执行不同的代码块,或者重复执行一段代码。在本篇博客中,我们将深入探讨C语言中的分支和循环语句。
一、分支语句
分支语句允许我们根据条件选择性地执行不同的代码块。在C语言中,我们有三种主要的分支语句:if语句、if-else语句和switch语句。
1.if语句
if语句是最简单的分支语句,它根据条件的真假来决定是否执行某段代码。if语句的基本语法如下:
if (condition) // 如果条件为真,执行这里的代码
{
text;
}
例如,我们可以使用if语句来判断一个数是否为正数:
int num = 10;
if (num > 0)
{
printf("这是一个正数\n");
}
以下是一些使用if语句时需要注意的事项:
1.确保条件表达式的类型为布尔值:if语句的条件表达式必须是一个布尔值(即只能为真或假)。 在C语言中,0代表假,非0值代表真。如果条件表达式不是布尔值,可能导致逻辑错误。
2.使用逻辑运算符组合条件:在if语句中,可以使用逻辑运算符(如&&、||、!)来组合多个条 件,以满足更复杂的判断需求。需要注意的是,逻辑运算符的优先级可能影响条件的判断结 果,建议使用括号来明确优先级。
3. 注意单独使用分号的陷阱:在if语句中,经常会出现单独使用分号的错误。例如,下面的代码会 出现逻辑错误:
if (num > 0);
{
printf("num大于0\n");
}
if(条件) 只能控制它后面的第一条语句,所以上面的代码中,分号导致if语句成为一个空语句,不会进行条件判断,而下面的代码块则无条件执行。正确的写法应该去掉分号:
if (num > 0)
{
printf("num大于0\n");
}
4. 使用大括号限定代码块:为了避免歧义和错误,建议在if语句中始终使用大括号来限定代码 块(这是if语句可以控制的语句)。即使代码块只有一行,也应该使用大括号来保持一致性和可 读性。
// 不推荐的写法
if (num > 0)
printf("num大于0\n");
// 推荐的写法
if (num > 0)
{
printf("num大于0\n");
}
5. 谨慎使用嵌套if语句:在多层嵌套if语句时,注意代码的可读性和维护性。如果嵌套层级过深, 可能会导致代码逻辑复杂、难以理解和维护。可以考虑使用逻辑运算符组合条件,或者使用更 合适的控制结构(如switch语句)来简化代码。
2.if-else语句
if-else语句在if语句的基础上增加了一个“否则”的分支,当条件为假时执行另一段代码。if-else语句的基本语法如下:
if (condition)
{ // 如果条件为真,执行这里的代码 }
else
{ // 如果条件为假,执行这里的代码 }
例如,我们可以使用if-else语句来判断一个数是正数还是负数:
int num = -5;
if (num > 0)
{
printf("这是一个正数\n");
}
else
{
printf("这是一个负数\n");
}
- 使用大括号限定代码块:为了避免歧义和错误,建议在if-else语句中始终使用大括号来限定代码块。即使代码块只有一行,也应该使用大括号来保持一致性和可读性。
// 不推荐的写法
if (num > 0)
printf("num大于0\n");
else
printf("num小于等于0\n");
// 推荐的写法
if (num > 0)
{
printf("num大于0\n");
}
else
{
printf("num小于等于0\n");
}
- 如果有多个 if 和 else ,可以记住这样⼀条规则, else 总是跟最接近的 if 匹配。
3.switch语句
switch语句允许我们根据不同的条件执行不同的代码块。它的语法如下:
switch (expression)
{
case constant1:
// 如果expression等于constant1,执行这里的代码
break;
case constant2:
// 如果expression等于constant2,执行这里的代码
break;
...
default:
// 如果expression不等于任何一个constant,执行这里的代码
break;
}
switch (表达式) {
case 常量1:
// 代码块1;
break;
case 常量2:
// 代码块2;
break;
...
case 常量n:
// 代码块n;
break;
default:
// 默认代码块;
break;
}
在上面的语法中,表达式的值会和每个case后面的常量进行比较,如果有匹配的常量,就会执行对应的代码块。当匹配到某个case后,程序会执行该case下面的代码,直到遇到break语句为止。如果没有匹配的常量,程序会执行default代码块中的内容。
需要注意的是,case后面的常量必须是整数或字符类型,且不能重复。另外,default代码块是可选的,当没有匹配的常量时,会执行default代码块中的内容。
以下是一个简单的示例,演示了switch语句的使用:
#include <stdio.h>
int main() {
int num = 2;
switch (num) {
case 1:
printf("数字为1\n");
break;
case 2:
printf("数字为2\n");
break;
case 3:
printf("数字为3\n");
break;
default:
printf("数字不在1-3之间\n");
}
return 0;
}
上面的示例中,根据变量num的值选择不同的输出语句。当num为1时,会输出"数字为1";当num为2时,会输出"数字为2";当num为3时,会输出"数字为3";其他情况下,会输出"数字不在1-3之间"。
通过上述示例,可以看出switch语句的便捷性和可读性。它能够以更简洁的方式处理多种选择情况,使代码更加易于维护和理解。
注意事项:
- case 和后边的数字之间必须有空格
- 每⼀个 case 语句中的代码执⾏完成后,需要加上 break ,才能跳出这个switch语句。
switch 语句也是分⽀效果的,只有在 switch 语句中使⽤ break 才能在跳出 switch语句,如果某⼀个 case 语句的后边没有 break 语句,代码会继续玩下执⾏,有可能执⾏其他 case 语句中的代码,直到遇到 break 语句或者 switch 语句结束。
所以在 switch 语句中 break 语句是⾮常重要的,能实现真正的分⽀效果。
在 switch 语句中 case 语句和 default 语句是没有顺序要求的,只要你的顺序是满⾜实际需求的就可以。不过我们通常是把 default ⼦句放在最后处理的 (此时可以不加break,否则就需要加上break)。
总结:
switch语句是C语言中的一种重要控制结构,可以根据不同的条件选择不同的执行路径。使用switch语句可以代替多个if-else语句,提高代码的可读性和易用性。但需要注意的是,case后面的常量必须是整数或字符类型,且不能重复。同时,default代码块是可选的,用于处理没有匹配到任何case的情况。
二、循环语句
循环语句允许我们重复执行一段代码,直到满足某个条件为止。在C语言中,我们有三种主要的循环语句:while循环、do-while循环和for循环。
1.while循环
while循环在执行循环体之前先判断条件是否为真,如果为真则执行循环体,然后再次判断条件。如果条件为假,则跳出循环。while循环的基本语法如下:
while (condition)
{
// 循环体
}
例如,我们可以使用while循环来输出1到10的数字:
int i = 1;
while (i <= 10)
{
printf("%d ", i);
i++;
}
while循环是一种基本的循环控制结构,它在每次循环开始前判断条件的真假,并根据结果决定是否继续执行循环体。
注意事项:
- 确保循环条件最终会变为 false,否则可能导致无限循环。
- 始终在循环体内更新循环条件,以确保循环能够正确终止。
- 避免在循环条件中进行复杂的计算,以提高代码的性能。
2.do-while循环
do-while循环先执行一次循环体,然后再判断条件是否为真。如果为真,则继续执行循环体,否则跳出循环。do-while循环的基本语法如下:
do
{
// 循环体
} while (condition);
例如,我们可以使用do-while循环来输出1到10的数字:
int i = 1;
do
{
printf("%d ", i);
i++;
} while (i <= 10);
do-while循环是一种先执行循环体再判断条件的循环控制结构,即使条件判断为false,也至少执行一次循环体。
注意事项:
- 确保循环条件最终会变为 false,否则可能导致无限循环。
- 始终在循环体内更新循环条件,以确保循环能够正确终止。
- 谨慎使用do-while循环,确保在特定情况下需要至少执行一次循环体。
3.for循环
for循环是最常用的循环语句,它在执行循环之前初始化一个计数器,然后在每次循环结束后更新计数器,并判断条件是否为真。如果为真,则继续执行循环体,否则跳出循环。
for 循环的语法形式如下:
for(表达式1; 表达式2; 表达式3)
语句;//如果循环体想包含更多的语句,可以加上⼤括号
- 表达式1 ⽤于循环变量的初始化
- 表达式2 ⽤于循环结束条件的判断
- 表达式3 ⽤于循环变量的调整
for (initialization; condition; update)
{
// 循环体
}
例如,我们可以使用for循环来输出1到10的数字:
for (int i = 1; i <= 10; i++)
{
printf("%d ", i);
}
break和continue语句
在C语言中,break和continue是两种常用的循环控制语句,它们可以帮助我们更灵活地控制循环的行为。在使用break和continue语句时,需要理解它们的作用和使用方式,以确保代码的正确性和可读性。
1.break语句
break语句用于终止当前循环,将执行的控制权转移到循环之后的下一条语句。当程序执行到break语句时,循环将立即终止,不再执行循环体中剩余的语句,并且继续执行循环外的代码。
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
break;//当i等于5后,就执⾏break,循环就终⽌了
printf("%d ", i);
i = i+1;
}
return 0;
}
break 的作⽤就是永久的终⽌循环,只要 break 被执⾏, break 外的第⼀层循环就终⽌了。 那以后我们在循环中,想在某种条件下终⽌循环,则可以使⽤ break 来完成我们想要的效果。
注意事项:
- break语句只能用于循环语句(如for、while、do-while循环)和switch语句中,用于跳出循环或结束switch语句的执行。
- 在嵌套循环中,break语句只会跳出当前的内层循环,而不会影响外层循环的执行,可以根据实际需求选择在哪一个循环中使用break语句。
- 在使用break语句时,需要仔细考虑循环终止的条件,避免出现死循环或永无终止的情况。
- 在某些特定情况下,可以使用标签(label)和break语句组合来实现跳出多重嵌套循环的目的,但过多使用标签和break语句可能会降低代码的可读性,建议谨慎使用。
2.continue语句
continue语句用于结束当前迭代的循环,继续执行下一次循环的迭代过程。当程序执行到continue语句时,循环体中剩余的语句将被跳过,直接进入下一次循环的判断条件。
#include <stdio.h>
int main()
{
int i = 1;
while(i<=10)
{
if(i == 5)
continue;
//当i等于5后,就执⾏continue,直接跳过continue的代码,去循环的判断的地⽅
//因为这⾥跳过了i = i+1,所以i⼀直为5,程序陷⼊和死循环
printf("%d ", i);
i = i+1;
}
return 0;
}
continue 可以帮助我们跳过某⼀次循环 continue 后边的代码,直接到循环的判断部分,进⾏下⼀次循环的判断,如果循环的调整是在 continue 后边的话,可能会造成死循环。
为了可以跳过打印5,我们可以这样修改代码:
#include <stdio.h>
int main()
{
int i = 1;
for(i=1; i<=10; i++)
{
if(i == 5)
continue;//这⾥continue跳过了后边的打印,来到了i++的调整部分
printf("%d ", i);
}
return 0;
}
注意事项:
- continue语句同样只能用于循环语句(如for、while、do-while循环),用于结束当前迭代,直接进行下一次循环迭代。
- 在嵌套循环中,continue语句只会结束当前内层循环的当前迭代,不会影响外层循环的执行。
- 使用continue语句时需要注意循环条件和迭代操作的正确性,避免出现死循环或永无终止的情况。
- 在某些特定情况下,可以使用标签和continue语句组合来实现跳过多重嵌套循环的目的,但同样需要谨慎使用,以免影响代码的可读性。
goto语句
在C语言中,goto语句是一种跳转语句,可以直接将程序的控制权转移到指定的标签处。它的基本用法是使用goto关键字后跟一个标签,例如:
goto label;
...
label: // 标签声明
下面是一些goto语句的常见用法:
1.无条件跳转:
使用goto语句可以在程序中无条件地跳转到指定的标签处。这种用法可以用于程序中的任何地方,用于提前结束循环、终止函数执行或在特定条件下直接跳转到指定位置,例如:
int i = 1;
start:
if (i <= 10) {
printf("%d\n", i);
i++;
goto start; // 无条件跳转到start标签处
}
注意事项:
谨慎使用无条件跳转,过多地使用goto语句可能导致程序逻辑混乱,降低代码的可读性和可维护性。
2.跳出多重嵌套循环:
在多重嵌套循环中,使用break语句只能跳出当前内层循环,而无法直接跳出外层循环。但可以利用标签和goto语句的组合,在满足特定条件时跳转到指定的标签处,从而实现跳出多重嵌套循环的目的,例如:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
goto end; // 跳出多层循环
}
printf("%d %d\n", i, j);
}
}
end:
3.注意事项:
过度使用goto语句来跳出多重嵌套循环可能会导致代码逻辑难以理解和维护。优先考虑使用其他更可以的控制语句或重构代码,例如使用标志变量来控制循环的终止。
总体而言,goto语句的使用应该谨慎,并遵守一些预定的规则以避免造成代码混乱。合理利用其他控制语句和编程技巧,可以避免过度使用goto语句,从而改善代码的可读性和可维护性。