【C语言】分支与循环(上)

【C语言】分支和循环(上)

程序流程控制是编程语言中用于设定代码执行顺序的核心部分。通过流程控制,我们可以实现条件判断、循环执行等复杂的逻辑,让程序变得"智能"。本文将详细梳理C语言中的分支与循环结构。

1. if 语句

if 语句是C语言中最基本的分支判断结构,用于根据条件的真假来决定是否执行某段代码。

1.1 if

if 语句的基本形式是,如果括号内的条件表达式为真(非0),则执行其后的语句。

c 复制代码
int age = 20;
if (age >= 18) {
    printf("已成年。\n");
}
1.2 else

elseif 配对使用,用于指定当 if 的条件为假(0)时需要执行的代码。

c 复制代码
int temperature = 15;
if (temperature > 25) {
    printf("天气炎热。\n");
} else {
    printf("天气凉爽。\n");
}
1.3 分支中包含多条语句

ifelse 分支需要执行的语句超过一条时,必须使用花括号 {} 将这些语句包裹起来,形成一个代码块。这是一个非常重要的编程规范。

c 复制代码
int is_logged_in = 1;
if (is_logged_in) {
    printf("欢迎回来!\n");
    printf("正在加载您的个人资料...\n");
} else {
    printf("您尚未登录。\n");
    printf("请先登录再进行操作。\n");
}
1.4 嵌套if

if 语句内部可以包含另一个 if 语句,形成嵌套结构,以实现更复杂的逻辑判断。

c 复制代码
int score = 85;
if (score >= 60) {
    printf("及格。\n");
    if (score >= 80) {
        printf("成绩良好。\n");
    }
} else {
    printf("不及格。\n");
}
1.5 悬空else问题

当存在多个 ifelse,但没有使用花括号时,else 会遵循就近原则 ,与离它最近且尚未配对的 if 结合。

c 复制代码
int a = 0, b = 2;
if (a == 1)
    if (b == 2)
        printf("A\n");
else // 这个else与 if(b == 2) 配对,而不是 if(a == 1)
    printf("B\n");

由于 a == 1 为假,整个外层 if 不执行,因此屏幕上什么都不会输出。为了避免这种混淆,最佳实践是始终为 ifelse 分支使用花括号,即使只有一条语句。

2. 关系操作符

关系操作符用于比较两个值,其结果为"真"(在C中通常表示为1)或"假"(表示为0)。

  • >: 大于
  • <: 小于
  • >=: 大于等于
  • <=: 小于等于
  • ==: 等于(注意:是两个等号,一个等号是赋值)
  • !=: 不等于

3. 条件操作符

条件操作符,也称为三元(或三目)操作符,是C语言中唯一一个需要三个操作数的运算符。它提供了一种 if-else 语句的紧凑写法。
语法条件 ? 表达式1 : 表达式2

如果"条件"为真,则整个表达式的值为"表达式1"的值;否则为"表达式2"的值。

c 复制代码
int a = 10, b = 20;
int max = (a > b) ? a : b; // 如果 a > b,max = a;否则 max = b
printf("最大值是: %d\n", max); // 输出 20

4. 逻辑操作符: &&, ||, !

逻辑操作符用于组合或修改关系表达式。

4.1 逻辑取反运算符 !

! 用于对一个表达式的逻辑值取反。真变假,假变真。

c 复制代码
int is_open = 0; // 0 表示假
if (!is_open) { // !is_open 为真
    printf("门是关着的。\n");
}
4.2 与运算符 &&

&& 表示逻辑"与"。只有当两边的表达式都为真时,整个表达式的结果才为真。

4.3 或运算符 ||

|| 表示逻辑"或"。只要两边的表达式中有一个为真,整个表达式的结果就为真。

4.4 练习:闰年的判断

一个年份是闰年的条件是:能被4整除但不能被100整除,或者能被400整除。

c 复制代码
int year = 2024;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
    printf("%d 是闰年。\n", year);
}
4.5 短路

逻辑运算符 &&|| 具有短路求值的特性。

  • 对于 expr1 && expr2,如果 expr1 为假,则 expr2 不会被求值,因为整个表达式的结果已确定为假。
  • 对于 expr1 || expr2,如果 expr1 为真,则 expr2 不会被求值 ,因为整个表达式的结果已确定为真。
    这个特性常用于在执行某个操作前先进行条件检查。

5. switch 语句

switch 语句是另一种分支结构,适用于根据一个整数或字符表达式的多个不同取值来执行不同的代码块。

5.1 if语句和switch语句的对比
  • if-else 适用于范围判断和复杂的逻辑组合。
  • switch 适用于对一个变量的多个离散常量值进行判断,代码结构通常更清晰。
5.2 switch语句中的 break

switch 结构中,case 只是一个入口标签。如果没有 break,程序会从匹配的 case 开始,穿透 并执行后续所有 casedefault 的代码,直到遇到 breakswitch 语句结束。因此,通常每个 case 块的末尾都需要一个 break

5.3 switch语句中的 default

default 子句是可选的。当表达式的值与所有 case 的常量值都不匹配时,default 后的代码块会被执行。

5.4 switch语句中的 casedefault 的顺序问题

casedefault 标签的出现顺序是任意的,不影响逻辑。但为了代码的可读性,通常将 default 放在所有 case 之后。

c 复制代码
char grade = 'B';
switch (grade) {
    case 'A':
        printf("优秀\n");
        break;
    case 'B':
        printf("良好\n");
        break;
    case 'C':
        printf("及格\n");
        break;
    default:
        printf("不及格\n");
        break;
}

6. while 循环

while 循环用于在给定条件为真时,重复执行一段代码。

6.1 if 和 while 的对比
  • if:只进行一次条件判断,代码块最多执行一次。
  • while:每次执行完循环体后,会再次进行条件判断,只要条件为真,就不断重复执行。
6.2 while语句的执行流程
  1. 判断 while 后的条件是否为真。
  2. 如果为假,跳出循环。
  3. 如果为真,执行循环体内的代码。
  4. 执行完毕后,返回第1步。
6.3 while循环的实践与练习

计算1到100的累加和。

c 复制代码
int i = 1;
int sum = 0;
while (i <= 100) {
    sum += i;
    i++;
}
printf("总和为: %d\n", sum);

7. for 循环

for 循环提供了一种更紧凑的循环结构,特别适合在循环次数已知的情况下使用。它将初始化、条件判断和更新三个部分集中在一起。
语法for (初始化; 条件; 更新)

c 复制代码
// 使用for循环计算1到100的累加和
int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum += i;
}
printf("总和为: %d\n", sum);

8. do-while 循环

do-while 循环与 while 类似,但它保证循环体至少被执行一次,因为它的条件判断在循环体执行之后。

8.1 语法形式与执行流程
  1. 执行 do 后面的循环体。
  2. 执行完毕后,判断 while 后的条件是否为真。
  3. 如果为真,返回第1步。
  4. 如果为假,跳出循环。
8.2 do while循环的实例与练习

一个简单的菜单程序,至少显示一次菜单。

c 复制代码
#include <stdio.h>
int main() {
    int choice;
    do {
        printf("请输入选项 (输入0退出): ");
        scanf("%d", &choice);
        // ... 处理选项 ...
    } while (choice != 0);
    printf("程序退出。\n");
    return 0;
}```

9. break和continue语句

breakcontinue 用于在循环内部提供更精细的控制。

  • break:立即终止 并跳出当前所在的整个循环(for, while, do-while)或 switch 语句。
  • continue跳过 本次循环中 continue 之后的剩余语句,并立即开始下一次循环的迭代。
9.1 在各种循环中使用
  • break举例:在1到10中寻找第一个能被7整除的数。
c 复制代码
for (int i = 1; i <= 10; i++) {
    if (i % 7 == 0) {
        printf("找到了: %d\n", i);
        break; // 找到后立即退出循环
    }
}
  • continue举例:打印1到10之间所有的奇数。
c 复制代码
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) { // 如果是偶数
        continue; // 跳过本次循环的printf,直接进入下一次迭代
    }
    printf("%d ", i);
}

10. 循环的嵌套

一个循环体内可以包含另一个完整的循环结构,形成嵌套循环。

10.1 练习:打印9x9乘法表
c 复制代码
#include <stdio.h>

int main() {
    // 题目解析:外层循环控制行(1到9),内层循环控制列。
    // 列的范围取决于当前是第几行。
    for (int i = 1; i <= 9; i++) { // 外层循环,控制行
        for (int j = 1; j <= i; j++) { // 内层循环,控制列
            printf("%d*%d=%-2d ", j, i, i * j); // %-2d表示左对齐,占2位宽度
        }
        printf("\n"); // 每打印完一行后换行
    }
    return 0;
}

11. goto 语句

goto 语句可以实现程序在任意位置之间的无条件跳转。它需要配合一个标签使用。

c 复制代码
// 示例(不推荐使用)
goto end_label;
printf("这行代码不会被执行\n");
end_label:
    printf("程序跳转到这里\n");

注意 :滥用 goto 语句会严重破坏程序的结构化,使代码逻辑混乱,难以阅读和维护,形成所谓的"意大利面条式代码"。在现代C语言编程中,应极力避免 使用 goto 语句。所有 goto 能实现的逻辑,都可以通过 if, switch, while, for, do-while 等结构化语句以更清晰的方式实现。

相关推荐
jllllyuz2 小时前
基于粒子群优化(PSO)的特征选择与支持向量机(SVM)分类
开发语言·算法·matlab
树下水月2 小时前
使用python 发送数据到第三方接口,同步等待太慢
开发语言·python
序属秋秋秋2 小时前
《Linux系统编程之进程基础》【进程状态】
linux·运维·c语言·c++·笔记·操作系统·进程状态
njsgcs2 小时前
pyautocad获得所选圆弧的弧长总和
开发语言·windows·python
xiaoxue..2 小时前
深入理解JavaScript中的深拷贝与浅拷贝:内存管理的艺术
开发语言·前端·javascript·面试
多多*2 小时前
分布式中间件 消息队列Rocketmq 详解
java·开发语言·jvm·数据库·mysql·maven·java-rocketmq
從南走到北2 小时前
JAVA外卖霸王餐CPS优惠CPS平台自主发布小程序+公众号霸王餐源码
java·开发语言·小程序
小龙报2 小时前
《嵌入式成长系列之51单片机 --- 固件烧录》
c语言·开发语言·单片机·嵌入式硬件·51单片机·创业创新·学习方法
xier_ran3 小时前
Python 切片(Slicing)完全指南:从基础到多维矩阵
开发语言·python·矩阵