二、C语言分支循环语句

目录

1、if语句

1.1 if语句的基本语法

1.1.1 单分支结构

1.1.2 双分支结构

1.1.3 多分支结构

1.2 if语句的核心规则

1.2.1 条件表达式

1.2.2 代码块与大括号

1.2.3 嵌套if语句

1.3 if语句的使用场景

1.3.1 数值范围判断

1.3.2 字符或枚举类型判断

1.3.3 逻辑组合判断

1.4 if语句的注意事项

1.4.1 常见错误

1.4.2 悬空else问题

1.5 if语句的优缺点

1.6 总结

2、switch语句

2.1 switch语句的基本语法

2.2 switch语句的执行逻辑

2.3 switch语句的使用场景

2.3.1 多分支离散值判断

2.3.2 字符类型处理

2.3.3 利用穿透特性合并分支

2.4 switch 语句的注意事项

2.4.1 csae值的限制

2.4.2 必须使用break

2.4.3 default的使用

2.5 switch vs if 的对比

2.6 示例代码

2.6.1 处理枚举类型

2.6.2 穿透特性实现多条件合并

2.7 总结

3、while语句

3.1 while语句的基本语法

3.2 while的核心特点

3.3 使用场景

3.3.1 用户输入验证

3.3.2 遍历数组或集合

3.3.3 动态条件循环

3.3.4 无限循环(需配合break)

3.4 注意事项

3.4.1 避免无限循环

3.4.2 条件表达式的副作用

3.4.3 复杂的退出条件

3.5 变体:do-while语句

3.6 总结

4、for语句

4.1 for语句的基本语法

4.2 for循环的典型使用场景

4.2.1 固定次数的循环

4.2.2 遍历数组或集合

4.2.3 倒序循环

4.2.4 多变量控制

4.3 for循环的灵活性

4.3.1 表达式可省略(但分号必须保留)

4.3.2 空循环体

4.3.3 嵌套循环

4.4 for vs while 的对比

4.5 注意事项

4.5.1 避免无限循环

4.5.2 循环变量作用域(C99起)

4.5.3 浮点数循环的精度问题

4.6 高级用法

4.6.1 逗号运算符

4.6.2 循环控制语句

4.7 总结


1、if语句

1.1 if语句的基本语法

1.1.1 单分支结构
if (条件表达式) {
    // 条件为真时执行的代码块
}
  • 执行逻辑:若条件表达式结果为真(非零),则执行代码块;否则跳过。

  • 示例

    int age = 18;
    if (age >= 18) {
        printf("成年人\n");  // 输出
    }
1.1.2 双分支结构
if (条件表达式) {
    // 条件为真时执行
} else {
    // 条件为假时执行
}
  • 执行逻辑:根据条件表达式结果选择执行其中一个分支。

  • 示例

    int score = 75;
    if (score >= 60) {
        printf("及格\n");  // 输出
    } else {
        printf("不及格\n");
    }
1.1.3 多分支结构
if (条件1) {
    // 条件1为真时执行
} else if (条件2) {
    // 条件2为真时执行
} else {
    // 所有条件均为假时执行
}
  • 执行逻辑:按顺序检查条件,执行第一个满足条件的分支。

  • 示例

    int temperature = 28;
    if (temperature > 30) {
        printf("炎热\n");
    } else if (temperature > 20) {
        printf("温暖\n");  // 输出
    } else {
        printf("凉爽\n");
    }

1.2 if语句的核心规则

1.2.1 条件表达式
  • 结果类型:必须是整型或布尔类型(C99起支持_Bool)。

  • 真值判断

    • 非零值为真(如5,-1,'A')。

    • 零值为假(如0,NULL)。

  • 常见形式

    if (a > b) { ... }          // 比较运算
    if (a && b) { ... }         // 逻辑与
    if (flag || error) { ... }  // 逻辑或
    if (!valid) { ... }         // 逻辑非
    
1.2.2 代码块与大括号
  • 单语句省略:若代码块仅一行,可省略大括号(但不建议)。

    if (x > 0) 
        printf("正数\n");  // 单语句可省略大括号
  • 多语句必须:多行代码必须使用大括号。

    if (x > 0) {
        printf("正数\n");
        x *= 2;  // 多语句必须用大括号
    }
1.2.3 嵌套if语句
  • 嵌套结构:if内部可包含另一个if。

    if (a > 0) {
        if (b > 0) {
            printf("a和b均为正数\n");
        }
    }
  • 注意缩进:嵌套时应合理缩进,避免逻辑混乱。


1.3 if语句的使用场景

1.3.1 数值范围判断
int score = 85;
if (score >= 90) {
    printf("A\n");
} else if (score >= 80) {
    printf("B\n");  // 输出
} else {
    printf("C\n");
}
1.3.2 字符或枚举类型判断
char op = '+';
if (op == '+') {
    printf("加法\n");  // 输出
} else if (op == '-') {
    printf("减法\n");
}
1.3.3 逻辑组合判断
int age = 25;
bool isStudent = true;

if (age >= 18 && isStudent) {
    printf("成年学生\n");  // 输出
}

1.4 if语句的注意事项

1.4.1 常见错误
  • 赋值运算符误用

    if (x = 5) { ... }  // 错误:将 x 赋值为5,条件永真

    修正:使用==:if(x == 5)

  • 浮点数精度问题

    float a = 0.1 + 0.2;
    if (a == 0.3) { ... }  // 可能不成立

    修正:使用误差范围:

    if (fabs(a - 0.3) < 1e-6) { ... }
1.4.2 悬空else问题
  • 代码歧义:else匹配最近的未匹配if。

    if (a > 0)
        if (b > 0)
            printf("a和b均为正数\n");
    else
        printf("a非正数\n");  // 实际匹配内层if

    修正:使用大括号明确作用域:

    if (a > 0) {
        if (b > 0) {
            printf("a和b均为正数\n");
        }
    } else {
        printf("a非正数\n");
    }

1.5 if语句的优缺点

优点

  • 灵活性:支持任意复杂的条件表达式。

  • 通用性:适用于所有数据类型(整型、浮点型、指针等)。

缺点

  • 效率问题:多分支时需逐条判断,效率可能低于switch。

  • 可读性:深层嵌套或复杂条件可能导致代码难以阅读。


1.6 总结

特性 说明
核心功能 根据条件选择执行代码分支
适用场景 范围判断、逻辑组合、错误处理等
语法要点 条件表达式必须为整型或布尔值,注意大括号使用
常见错误 误用 = 代替 ==,浮点数精度问题,悬空else
与switch对比 if更灵活,switch适合离散值多分支

2、switch语句

2.1 switch语句的基本语法

switch (表达式) {
    case 常量1:
        // 代码块1
        break;
    case 常量2:
        // 代码块2
        break;
    ...
    default:
        // 默认代码块
        break;
}
  • 核心组成部分

  1. switch(表达式)

    • 表达式必须是 整型 或 枚举类型(如int、char)。

    • 不支持浮点数、字符串或其他复杂类型。

  2. csae 常量:

    • case后跟一个整型常量表达式(如1、'A'),不能是变量或表达式。

    • 所有case的常量值必须唯一。

  3. break;

    • 用于退出switch语句,防止代码“穿透”到下一个case。

  4. default:

    • 当所有case均不匹配时执行。

    • default可以省略,但建议保留以处理意外情况。


2.2 switch语句的执行逻辑

  1. 计算表达式:先计算switch后的表达式值。

  2. 匹配case:从上到下依次与各case的常量值匹配。

  3. 执行代码块:找到匹配的case后,执行其代码块。

  4. 退出或穿透

    • 遇到break时退出整个switch。

    • 若无break,代码会继续执行下一个case的代码块(称为 穿透)。


2.3 switch语句的使用场景

2.3.1 多分支离散值判断
  • 示例:菜单选择、状态码处理。

int choice = 2;
switch (choice) {
    case 1:
        printf("开始游戏\n");
        break;
    case 2:
        printf("加载存档\n");  // 输出
        break;
    default:
        printf("无效选项\n");
        break;
}
2.3.2 字符类型处理
  • 示例:解析用户输入的字符指令。

char command = 'S';
switch (command) {
    case 'N':
        printf("向北移动\n");
        break;
    case 'S':
        printf("向南移动\n");  // 输出
        break;
    default:
        printf("未知指令\n");
        break;
}
2.3.3 利用穿透特性合并分支
  • 示例:多个case共享同一段代码。

int month = 2;
switch (month) {
    case 1:
    case 3:
    case 5:
        printf("31天\n");
        break;
    case 2:
        printf("28或29天\n");  // 输出
        break;
    default:
        printf("30天\n");
        break;
}

2.4 switch 语句的注意事项

2.4.1 csae值的限制
  • 必须是常量:csae后不能使用变量或表达式。

    int x = 10;
    switch (x) {
        case 5 + 5:  // 合法(常量表达式)
            printf("10\n");
            break;
        case x:      // 非法(x 是变量)
            printf("error\n");
            break;
    }
2.4.2 必须使用break
  • 穿透问题:若省略break,代码会继续执行后续csae。

    int num = 1;
    switch (num) {
        case 1:
            printf("1\n");  // 输出
            // 缺少 break
        case 2:
            printf("2\n");  // 也会输出
            break;
    }
2.4.3 default的使用
  • 非必须但建议:处理未覆盖的情况。

    int code = 404;
    switch (code) {
        case 200:
            printf("成功\n");
            break;
        default:
            printf("错误代码: %d\n", code);  // 输出 "错误代码: 404"
            break;
    }

2.5 switch vs if 的对比

特性 switch 语句 if 语句
条件类型 仅整型或枚举类型 任意布尔表达式
分支逻辑 基于离散值匹配 支持范围判断和复杂逻辑
效率 分支多时可能优化为跳转表 逐条判断,效率可能较低
可读性 适合多分支离散值 适合简单或复杂条件
常见错误 忘记break导致穿透 误用 = 代替 ==

2.6 示例代码

2.6.1 处理枚举类型
enum Color { RED, GREEN, BLUE };
enum Color c = GREEN;

switch (c) {
    case RED:
        printf("红色\n");
        break;
    case GREEN:
        printf("绿色\n");  // 输出
        break;
    case BLUE:
        printf("蓝色\n");
        break;
}
2.6.2 穿透特性实现多条件合并
char grade = 'B';
switch (grade) {
    case 'A':
    case 'B':
    case 'C':
        printf("合格\n");  // 输出
        break;
    case 'D':
    case 'F':
        printf("不合格\n");
        break;
}

2.7 总结

特性 说明
核心功能 基于离散值匹配执行多分支代码
适用场景 菜单选择、状态码处理、字符指令解析
语法要点 case后必须为整型常量,break防止穿透,default处理未匹配情况
常见错误 忘记 break,case使用变量或非整型值
性能优势 分支较多时可能被编译器优化为跳转表

3、while语句

3.1 while语句的基本语法

while (条件表达式) {
    // 循环体代码块
}
  • 执行逻辑

    1. 先判断条件表达式是否为真(非零)。

    2. 若为真,执行循环体代码块,然后重复步骤1。

    3. 若为假,退出循环。


3.2 while的核心特点

  1. 先判断后执行:可能一次都不执行循环体(条件初始即为假)。

  2. 适合不确定次数的循环:循环次数由动态条件决定。

  3. 灵活性:条件可以是任意布尔表达式(整型、逻辑运算等)。


3.3 使用场景

3.3.1 用户输入验证
int num;
printf("请输入一个正数: ");
scanf("%d", &num);
while (num <= 0) {  // 若输入不合法,循环提示
    printf("输入错误!请重新输入: ");
    scanf("%d", &num);
}
3.3.2 遍历数组或集合
int arr[] = {1, 2, 3, 4, 5};
int i = 0;
while (i < 5) {
    printf("%d ", arr[i]);  // 输出: 1 2 3 4 5
    i++;
}
3.3.3 动态条件循环
int x = 10;
while (x > 0) {
    printf("%d ", x);  // 输出: 10 9 8 ... 1
    x--;
}
3.3.4 无限循环(需配合break)
while (1) {  // 条件永真
    printf("按Q退出: ");
    char c = getchar();
    if (c == 'Q') break;  // 手动退出
}

3.4 注意事项

3.4.1 避免无限循环
  • 错误示例:未更新循环变量。

    int i = 0;
    while (i < 5) {  // i 始终为0,条件永真
        printf("无限循环\n");
    }
  • 修正:在循环体内更新变量。

    int i = 0;
    while (i < 5) {
        printf("%d\n", i);
        i++;  // 更新条件变量
    }
3.4.2 条件表达式的副作用
  • 避免在条件中修改变量(除非必要)。

    int x = 5;
    while (x-- > 0) {  // 合法,但可能降低可读性
        printf("%d ", x);  // 输出: 4 3 2 1 0
    }
3.4.3 复杂的退出条件
  • 若循环退出条件复杂,可结合break使用。

    while (1) {
        // 复杂逻辑...
        if (满足退出条件) break;
    }

3.5 变体:do-while语句

  • 语法:
do {
    // 循环体代码块
} while (条件表达式);
  • 特点先执行后判断,循环体至少执行一次。

  • 适用场景:菜单界面、至少执行一次的操作。

    int choice;
    do {
        printf("1. 开始\n2. 退出\n");
        scanf("%d", &choice);
    } while (choice != 1 && choice != 2);  // 输入非法时重复

3.6 总结

特性 说明
核心功能 根据条件重复执行代码块
执行逻辑 先判断条件,后执行循环体
适用场景 输入验证、动态条件循环、不确定次数的操作
常见错误 忘记更新循环变量导致无限循环,条件表达式副作用
与for对比 while更灵活,for更紧凑

4、for语句

4.1 for语句的基本语法

for (初始化表达式; 条件表达式; 更新表达式) {
    // 循环体代码块
}
  • 核心组成部分

  1. 初始化表达式

    • 在循环开始前执行一次,通常用于初始化循环变量。

    • 可以声明变(C99起支持循环内声明,如 for(int i = 0; ; ...))。

  2. 条件表达式

    • 每次循环前检查条件,若为真(非零)则执行循环体,否则退出循环。

  3. 更新表达式

    • 每次循环体执行后执行,通常用于更新循环变量。


4.2 for循环的典型使用场景

4.2.1 固定次数的循环
for (int i = 0; i < 5; i++) {
    printf("%d ", i);  // 输出: 0 1 2 3 4
}
4.2.2 遍历数组或集合
int arr[] = {10, 20, 30};
for (int i = 0; i < 3; i++) {
    printf("%d ", arr[i]);  // 输出: 10 20 30
}
4.2.3 倒序循环
for (int i = 5; i > 0; i--) {
    printf("%d ", i);  // 输出: 5 4 3 2 1
}
4.2.4 多变量控制
for (int i = 0, j = 10; i < j; i++, j--) {
    printf("%d-%d ", i, j);  // 输出: 0-10 1-9 2-8 ... 4-6
}

4.3 for循环的灵活性

4.3.1 表达式可省略(但分号必须保留)
int i = 0;
for (; i < 5; ) {  // 省略初始化和更新表达式(等效于 while 循环)
    printf("%d ", i);
    i++;
}
4.3.2 空循环体
for (int i = 0; i < 1000000; i++);  // 空循环,常用于延时
4.3.3 嵌套循环
for (int i = 0; i < 3; i++) {        // 外层循环
    for (int j = 0; j < 2; j++) {    // 内层循环
        printf("(%d,%d) ", i, j);    // 输出: (0,0) (0,1) (1,0) (1,1) (2,0) (2,1)
    }
}

4.4 for vs while 的对比

特性 for 语句 while 语句
代码结构 集成初始化、条件、更新,结构紧凑 初始化在循环外,更新在循环体内
适用场景 循环次数已知或需要明确控制变量 循环次数不确定或动态条件
变量作用域 C99起支持循环内变量声明(局部作用域) 变量需在循环外声明
可读性 适合固定模式的循环,逻辑集中 适合复杂条件或动态退出逻辑

4.5 注意事项

4.5.1 避免无限循环
  • 错误示例:条件表达式永真。

    for (int i = 0; i >= 0; i++) {  // i 始终 ≥0,无限循环
        printf("%d ", i);
    }
4.5.2 循环变量作用域(C99起)
  • 循环内声明变量:仅在循环体内有效。

    for (int i = 0; i < 5; i++) {
        printf("%d ", i);  // i 仅在循环内可见
    }
    // printf("%d", i);    // 错误:i 未定义
4.5.3 浮点数循环的精度问题
  • 错误示例:浮点数精度丢失导致循环次数异常。

    for (float x = 0.1; x != 1.0; x += 0.1) {  // 可能无限循环
        printf("%f ", x);
    }

    修正:改用整数控制循环。

    for (int i = 1; i <= 10; i++) {
        float x = i * 0.1;
        printf("%f ", x);
    }

4.6 高级用法

4.6.1 逗号运算符
  • 在初始化或更新表达式中使用逗号分隔多个操作。

    for (int i = 0, j = 10; i < j; i++, j--) {
        printf("%d-%d ", i, j);  // 输出: 0-10 1-9 ... 4-6
    }
4.6.2 循环控制语句
  • break:立即退出整个循环。

    for (int i = 0; i < 10; i++) {
        if (i == 5) break;  // 循环在 i=5 时终止
        printf("%d ", i);   // 输出: 0 1 2 3 4
    }
  • continue:跳过本次循环剩余代码,进入下一轮循环。

    for (int i = 0; i < 5; i++) {
        if (i == 2) continue;
        printf("%d ", i);  // 输出: 0 1 3 4
    }

4.7 总结

特性 说明
核心功能 通过初始化、条件、更新表达式实现紧凑的循环控制
适用场景 固定次数循环、数组遍历、多变量控制
优势 结构清晰,集成循环控制逻辑,减少代码冗余
常见错误 浮点数精度问题、无限循环、变量作用域混淆
与while对比 for更紧凑,适合明确循环次数;while更灵活,适合动态条件循环

你可能感兴趣的:(c语言,开发语言)