Skip to content

流程控制

流程控制语句用于控制程序的执行顺序。C语言提供了条件语句和循环语句来控制程序流程。本章将详细介绍C语言的流程控制语句。

条件语句

if语句

c
/*
 * if语句
 */

#include <stdio.h>

int main(void)
{
    int score = 75;
    
    /* 基本if语句 */
    if (score >= 60) {
        printf("及格了!\n");
    }
    
    /* if-else语句 */
    if (score >= 60) {
        printf("及格\n");
    } else {
        printf("不及格\n");
    }
    
    /* if-else if-else语句 */
    if (score >= 90) {
        printf("优秀\n");
    } else if (score >= 80) {
        printf("良好\n");
    } else if (score >= 60) {
        printf("及格\n");
    } else {
        printf("不及格\n");
    }
    
    /* 嵌套if语句 */
    int age = 25;
    int has_license = 1;
    
    if (age >= 18) {
        printf("成年了\n");
        if (has_license) {
            printf("可以开车\n");
        } else {
            printf("需要先考驾照\n");
        }
    } else {
        printf("未成年\n");
    }
    
    /* 单语句可以省略大括号(不推荐) */
    if (score >= 60)
        printf("及格\n");  /* 只有一条语句 */
    else
        printf("不及格\n");
    
    /* 推荐始终使用大括号 */
    if (score >= 60) {
        printf("及格\n");
    } else {
        printf("不及格\n");
    }
    
    return 0;
}

switch语句

c
/*
 * switch语句
 */

#include <stdio.h>

int main(void)
{
    int day = 3;
    
    /* 基本switch语句 */
    switch (day) {
        case 1:
            printf("星期一\n");
            break;  /* 跳出switch */
        case 2:
            printf("星期二\n");
            break;
        case 3:
            printf("星期三\n");
            break;
        case 4:
            printf("星期四\n");
            break;
        case 5:
            printf("星期五\n");
            break;
        case 6:
            printf("星期六\n");
            break;
        case 7:
            printf("星期日\n");
            break;
        default:  /* 默认情况 */
            printf("无效的日期\n");
            break;
    }
    
    /* 没有break的穿透效果 */
    char grade = 'B';
    
    switch (grade) {
        case 'A':
            printf("优秀\n");
            /* 没有break,继续执行下一个case */
        case 'B':
            printf("良好\n");
            /* 没有break,继续执行 */
        case 'C':
            printf("及格\n");
            break;  /* 这里break */
        case 'D':
            printf("不及格\n");
            break;
        default:
            printf("无效等级\n");
    }
    /* 输出:良好\n及格\n */
    
    /* 多个case共享代码 */
    int month = 2;
    
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            printf("%d月有31天\n", month);
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            printf("%d月有30天\n", month);
            break;
        case 2:
            printf("%d月有28或29天\n", month);
            break;
        default:
            printf("无效月份\n");
    }
    
    /* switch中的变量声明 */
    switch (day) {
        case 1: {
            int temp = 100;  /* 需要用大括号包围 */
            printf("temp = %d\n", temp);
            break;
        }
        default:
            break;
    }
    
    return 0;
}

条件运算符

c
/*
 * 条件运算符实现简单的条件判断
 */

#include <stdio.h>

int main(void)
{
    int a = 10, b = 5;
    
    /* 使用条件运算符 */
    int max = (a > b) ? a : b;
    printf("最大值: %d\n", max);
    
    int min = (a < b) ? a : b;
    printf("最小值: %d\n", min);
    
    /* 判断奇偶 */
    int num = 7;
    printf("%d%s\n", num, (num % 2 == 0) ? "偶数" : "奇数");
    
    /* 求绝对值 */
    int x = -5;
    int abs_x = (x >= 0) ? x : -x;
    printf("|%d| = %d\n", x, abs_x);
    
    return 0;
}

循环语句

while循环

c
/*
 * while循环
 */

#include <stdio.h>

int main(void)
{
    /* 基本while循环 */
    int i = 1;
    while (i <= 5) {
        printf("i = %d\n", i);
        i++;  /* 更新循环变量 */
    }
    
    /* 计算1到100的和 */
    int sum = 0;
    int n = 1;
    while (n <= 100) {
        sum += n;
        n++;
    }
    printf("1到100的和: %d\n", sum);
    
    /* 无限循环 */
    int count = 0;
    while (1) {  /* 条件始终为真 */
        printf("count = %d\n", count);
        count++;
        if (count >= 3) {
            break;  /* 跳出循环 */
        }
    }
    
    /* 输入验证 */
    int input;
    printf("请输入一个正数: ");
    scanf("%d", &input);
    
    while (input <= 0) {
        printf("输入无效,请重新输入: ");
        scanf("%d", &input);
    }
    printf("你输入的正数是: %d\n", input);
    
    /* 读取输入直到特定值 */
    int value;
    printf("输入数字(输入0结束):\n");
    
    while (scanf("%d", &value) == 1 && value != 0) {
        printf("你输入了: %d\n", value);
    }
    printf("循环结束\n");
    
    return 0;
}

do-while循环

c
/*
 * do-while循环
 */

#include <stdio.h>

int main(void)
{
    /* 基本do-while循环 */
    /* 注意:循环体至少执行一次 */
    int i = 1;
    do {
        printf("i = %d\n", i);
        i++;
    } while (i <= 5);
    
    /* 与while的区别 */
    int x = 10;
    
    /* while循环:条件不满足时不执行 */
    while (x < 5) {
        printf("while: x = %d\n", x);  /* 不会执行 */
    }
    
    /* do-while循环:至少执行一次 */
    do {
        printf("do-while: x = %d\n", x);  /* 会执行一次 */
    } while (x < 5);
    
    /* 菜单选择 */
    int choice;
    
    do {
        printf("\n=== 菜单 ===\n");
        printf("1. 新游戏\n");
        printf("2. 继续游戏\n");
        printf("3. 设置\n");
        printf("4. 退出\n");
        printf("请选择: ");
        scanf("%d", &choice);
        
        switch (choice) {
            case 1:
                printf("开始新游戏\n");
                break;
            case 2:
                printf("继续游戏\n");
                break;
            case 3:
                printf("打开设置\n");
                break;
            case 4:
                printf("退出\n");
                break;
            default:
                printf("无效选择,请重试\n");
        }
    } while (choice != 4);
    
    /* 数字反转 */
    int num = 12345;
    int reversed = 0;
    
    do {
        reversed = reversed * 10 + num % 10;
        num /= 10;
    } while (num != 0);
    
    printf("反转后的数字: %d\n", reversed);
    
    return 0;
}

for循环

c
/*
 * for循环
 */

#include <stdio.h>

int main(void)
{
    /* 基本for循环 */
    /* for (初始化; 条件; 更新) */
    for (int i = 1; i <= 5; i++) {
        printf("i = %d\n", i);
    }
    
    /* 计算1到100的和 */
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    printf("1到100的和: %d\n", sum);
    
    /* 遍历数组 */
    int arr[] = {10, 20, 30, 40, 50};
    int len = sizeof(arr) / sizeof(arr[0]);
    
    for (int i = 0; i < len; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }
    
    /* 省略部分表达式 */
    int j = 0;
    for (; j < 5; j++) {  /* 省略初始化 */
        printf("j = %d\n", j);
    }
    
    for (int k = 0; ; k++) {  /* 省略条件 */
        if (k >= 5) break;
        printf("k = %d\n", k);
    }
    
    /* 无限循环 */
    for (;;) {
        printf("无限循环\n");
        break;  /* 立即跳出 */
    }
    
    /* 多个循环变量 */
    for (int i = 0, j = 10; i < j; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    
    /* 嵌套for循环:打印乘法表 */
    printf("\n=== 九九乘法表 ===\n");
    for (int i = 1; i <= 9; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%d*%d=%-2d ", j, i, i * j);
        }
        printf("\n");
    }
    
    /* 打印图形 */
    printf("\n=== 打印三角形 ===\n");
    for (int i = 1; i <= 5; i++) {
        for (int j = 1; j <= i; j++) {
            printf("* ");
        }
        printf("\n");
    }
    
    return 0;
}

跳转语句

break语句

c
/*
 * break语句
 */

#include <stdio.h>

int main(void)
{
    /* 在循环中使用break */
    for (int i = 1; i <= 10; i++) {
        if (i == 5) {
            printf("遇到5,跳出循环\n");
            break;  /* 跳出整个循环 */
        }
        printf("i = %d\n", i);
    }
    
    /* 在switch中使用break */
    char grade = 'B';
    switch (grade) {
        case 'A':
            printf("优秀\n");
            break;
        case 'B':
            printf("良好\n");
            break;  /* 跳出switch */
        default:
            printf("其他\n");
    }
    
    /* 查找元素 */
    int arr[] = {3, 7, 2, 9, 5};
    int target = 9;
    int found = -1;
    int len = sizeof(arr) / sizeof(arr[0]);
    
    for (int i = 0; i < len; i++) {
        if (arr[i] == target) {
            found = i;
            break;  /* 找到后立即退出 */
        }
    }
    
    if (found != -1) {
        printf("找到 %d 在索引 %d\n", target, found);
    } else {
        printf("未找到 %d\n", target);
    }
    
    /* 嵌套循环中的break */
    for (int i = 1; i <= 3; i++) {
        for (int j = 1; j <= 3; j++) {
            if (i == 2 && j == 2) {
                printf("跳出内层循环\n");
                break;  /* 只跳出内层循环 */
            }
            printf("(%d, %d) ", i, j);
        }
        printf("\n");
    }
    
    return 0;
}

continue语句

c
/*
 * continue语句
 */

#include <stdio.h>

int main(void)
{
    /* 跳过当前迭代,继续下一次 */
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            continue;  /* 跳过偶数 */
        }
        printf("奇数: %d\n", i);
    }
    
    /* 跳过特定元素 */
    int arr[] = {1, -2, 3, -4, 5, -6};
    int len = sizeof(arr) / sizeof(arr[0]);
    
    printf("正数有: ");
    for (int i = 0; i < len; i++) {
        if (arr[i] < 0) {
            continue;  /* 跳过负数 */
        }
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    /* 在while循环中使用continue */
    int i = 0;
    while (i < 10) {
        i++;
        if (i % 3 == 0) {
            continue;  /* 跳过3的倍数 */
        }
        printf("不是3的倍数: %d\n", i);
    }
    
    /* 统计字符 */
    char str[] = "Hello, World!";
    int letter_count = 0;
    int i = 0;
    
    while (str[i] != '\0') {
        /* 跳过非字母字符 */
        if (!((str[i] >= 'a' && str[i] <= 'z') || 
              (str[i] >= 'A' && str[i] <= 'Z'))) {
            i++;
            continue;
        }
        letter_count++;
        i++;
    }
    printf("字母数量: %d\n", letter_count);
    
    return 0;
}

goto语句

c
/*
 * goto语句
 */

#include <stdio.h>

int main(void)
{
    /* 基本goto使用 */
    int i = 0;
    
start:  /* 标签 */
    printf("i = %d\n", i);
    i++;
    if (i < 3) {
        goto start;  /* 跳转到标签 */
    }
    
    printf("循环结束\n");
    
    /* 使用goto跳出嵌套循环 */
    int found = 0;
    
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (i * j == 12) {
                found = 1;
                goto found_label;  /* 一次跳出多层循环 */
            }
        }
    }
    
found_label:
    if (found) {
        printf("找到了满足条件的点\n");
    } else {
        printf("未找到\n");
    }
    
    /* 错误处理 */
    int *ptr = NULL;
    
    if (ptr == NULL) {
        goto error;
    }
    
    /* 正常处理代码 */
    *ptr = 10;
    printf("正常执行\n");
    goto end;
    
error:
    printf("错误:空指针\n");
    
end:
    printf("程序结束\n");
    
    /* 注意:过度使用goto会使代码难以理解 */
    /* 建议:尽量使用其他控制结构代替goto */
    
    return 0;
}

return语句

c
/*
 * return语句
 */

#include <stdio.h>

/* 返回值的函数 */
int add(int a, int b)
{
    return a + b;  /* 返回计算结果 */
}

/* 提前返回 */
int find_max(int arr[], int len)
{
    if (len <= 0) {
        return -1;  /* 提前返回错误值 */
    }
    
    int max = arr[0];
    for (int i = 1; i < len; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    return max;  /* 返回最大值 */
}

/* 无返回值的函数 */
void print_line(int n)
{
    for (int i = 0; i < n; i++) {
        printf("-");
    }
    printf("\n");
    return;  /* 可以省略 */
}

int main(void)
{
    /* 使用返回值 */
    int result = add(5, 3);
    printf("5 + 3 = %d\n", result);
    
    /* 提前返回 */
    int arr[] = {3, 7, 2, 9, 5};
    int max = find_max(arr, 5);
    printf("最大值: %d\n", max);
    
    int empty_max = find_max(arr, 0);
    printf("空数组返回: %d\n", empty_max);
    
    /* void函数 */
    print_line(20);
    
    /* main函数返回 */
    printf("程序正常结束\n");
    return 0;  /* 返回状态码 */
}

循环应用实例

素数判断

c
/*
 * 素数判断
 */

#include <stdio.h>
#include <stdbool.h>

/* 判断是否为素数 */
bool is_prime(int n)
{
    if (n <= 1) return false;
    if (n <= 3) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    
    for (int i = 5; i * i <= n; i += 6) {
        if (n % i == 0 || n % (i + 2) == 0) {
            return false;
        }
    }
    return true;
}

int main(void)
{
    /* 判断单个数字 */
    int num = 17;
    if (is_prime(num)) {
        printf("%d 是素数\n", num);
    } else {
        printf("%d 不是素数\n", num);
    }
    
    /* 输出100以内的素数 */
    printf("\n100以内的素数:\n");
    int count = 0;
    for (int i = 2; i <= 100; i++) {
        if (is_prime(i)) {
            printf("%3d ", i);
            count++;
            if (count % 10 == 0) {
                printf("\n");
            }
        }
    }
    printf("\n%d个素数\n", count);
    
    return 0;
}

斐波那契数列

c
/*
 * 斐波那契数列
 */

#include <stdio.h>

int main(void)
{
    int n = 20;
    
    /* 方法1:迭代 */
    printf("斐波那契数列前%d项:\n", n);
    
    long long a = 0, b = 1;
    printf("%lld %lld ", a, b);
    
    for (int i = 3; i <= n; i++) {
        long long c = a + b;
        printf("%lld ", c);
        a = b;
        b = c;
    }
    printf("\n");
    
    /* 方法2:数组存储 */
    long long fib[50];
    fib[0] = 0;
    fib[1] = 1;
    
    for (int i = 2; i < n; i++) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }
    
    printf("\n使用数组:\n");
    for (int i = 0; i < n; i++) {
        printf("%lld ", fib[i]);
        if ((i + 1) % 10 == 0) {
            printf("\n");
        }
    }
    printf("\n");
    
    return 0;
}

猜数字游戏

c
/*
 * 猜数字游戏
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    /* 设置随机种子 */
    srand((unsigned int)time(NULL));
    
    /* 生成1-100的随机数 */
    int target = rand() % 100 + 1;
    int guess;
    int attempts = 0;
    
    printf("=== 猜数字游戏 ===\n");
    printf("我想了一个1到100之间的数字\n");
    printf("请猜猜是多少?\n\n");
    
    while (1) {
        printf("请输入你的猜测: ");
        scanf("%d", &guess);
        attempts++;
        
        if (guess < target) {
            printf("太小了!再试试\n");
        } else if (guess > target) {
            printf("太大了!再试试\n");
        } else {
            printf("\n恭喜你!猜对了!\n");
            printf("答案是: %d\n", target);
            printf("你用了%d次猜中\n", attempts);
            break;
        }
    }
    
    /* 评价 */
    if (attempts <= 5) {
        printf("太厉害了!你是猜数字天才!\n");
    } else if (attempts <= 10) {
        printf("表现不错!\n");
    } else {
        printf("继续加油!\n");
    }
    
    return 0;
}

小结

本章学习了:

  • 条件语句:if、if-else、if-else if-else、switch
  • 循环语句:while、do-while、for
  • 跳转语句:break、continue、goto、return
  • 循环应用:素数判断、斐波那契数列、猜数字游戏

下一章,我们将学习函数,了解C语言函数的定义和使用。