一文带你掌握C语言的分支结构

发布时间 2023-11-30 20:51:41作者: 顾平安

C语言分支结构详解

1. if 语句

在本篇博客文章中,我们将深入探讨C语言中的if语句及其相关用法。if语句是一种用于条件判断的分支语句,它允许我们根据条件的真假来执行不同的代码块。

1.1 if 语句的基本语法和用法

if语句的基本语法如下所示:

if (条件) {
    // 条件为真时执行的代码块
}

在这个语法结构中,条件是一个布尔表达式,如果条件的值为真(非零),则执行if语句块中的代码。

1.2 else 语句和 else if 语句的使用

除了 if 语句,我们还可以使用 else 语句和 else if 语句来处理条件的不同情况。else 语句在 if 条件以及 else if 条件(假设存在)均为假时执行,而 else if 语句用于在多个条件之间进行判断。

ifelse if 均需条件,从 if 往下遍历条件,若所有条件不符合,执行 else 后的代码。

int num = 10;

if (num > 0) {
    printf("数字是正数\n");
} else if (num < 0) {
    printf("数字是负数\n");
} else {
    printf("数字是 0\n");
}

在这个示例中,我们根据 num 的值输出不同的结果。如果 num 大于0,我们打印"数字是正数";如果 num 小于0,我们打印"数字是负数";如果 num 等于0(不大于0且不小于0,就是0),因此我们打印"数字是 0"。

1.3 if 语句的嵌套和多重条件判断

在C语言中,我们可以嵌套if语句,这意味着在一个 if 语句块内部包含另一个if语句块。这样可以实现更复杂的条件判断逻辑。

int num = 10;

if (num > 0) {
    if (num % 2 == 0) {
        printf("数字是正偶数\n");
    } else {
        printf("数字是正奇数\n");
    }
} else if (num < 0) {
    printf("数字是负数\n");
} else {
    printf("数字是 0\n");
}

在这个示例中,我们首先判断num是否大于0,如果是,则进一步判断num是否为偶数或奇数。根据条件的不同,我们输出相应的结果。

1.4 悬空 else 问题及其解决方法

在C语言中,else 语句总是与最近的 if 语句配对,这就导致了一个被称为"悬空 else"的问题。当我们有多个嵌套的if语句时,可能会出现 else 语句与我们预期的 if 语句不匹配的情况。

为了解决悬空 else 问题,可以使用花括号(代码块)来明确 if 语句的范围,从而避免 else 语句与错误的 if 语句配对。

首先请看这个示例,初学者可能发现预期的输出和实际的输出有出入。

int num = -10;

if (num > 0)
    if (num % 2 == 0)
        printf("数字是正偶数\n");
else
    printf("数字是负数\n");

在这个示例中,初学者会下意识的根据缩进格式来判断,理所当然的认为上述代码打印"数字是负数",实际情况是什么都不会打印!!!因为else 语句总是与最近的 if 语句配对

截图_20231130195637

我们使用了花括号将 if 语句的范围明确标记出来,从而避免了悬空 else 问题。

int num = -10;

if (num > 0) {
    if (num % 2 == 0) {
        printf("数字是正偶数\n");
    }
} else {
    printf("数字是负数\n");
}

2. 关系操作符

在本节中,我们将介绍C语言中常用的关系操作符。在C语言中,任何非零值都被视为真(true),而零值被视为假(false)。关系运算符的结果大致上可以认为返回的是 bool 类型的 true 或者 false,但是,严格来说是int类型的1(表示真)或0(表示假)。

2.1 关系操作符的种类和用法

C语言中的关系操作符包括以下几种:

  • ==:等于
  • !=:不等于
  • >:大于
  • <:小于
  • >=:大于等于
  • <=:小于等于

我们可以使用这些操作符在条件判断中比较两个值的大小关系。

2.2 关系操作符的返回值类型

关系操作符的返回值类型是布尔类型,即 int 型的0或1。当关系成立时,返回1(真),否则返回0(假)。

2.3 关系操作符在条件判断中的应用

关系操作符常常用于条件判断语句中,例如 if 语句、while 循环等。通过比较两个值的大小关系,我们可以根据条件的真假来执行不同的代码块。

下面是一个使用关系操作符的示例:

int a = 5, b = 10;

if (a == b) {
    printf("a 与 b 相等\n");
} else if (a < b) {
    printf("a 比 b 小\n");
} else {
    printf("a 比 b 大\n");
}

在这个示例中,我们比较了变量a和b的值,并根据比较结果输出不同的结果。

3. 条件操作符

条件操作符(也称为三元运算符、三目运算符)是C语言中一种简洁的条件表达式。它允许我们根据条件的真假选择不同的值。

3.1 条件操作符的语法和用法

条件操作符的语法如下所示:

条件 ? 表达式1 : 表达式2

如果条件为真,则返回表达式1的值;如果条件为假,则返回表达式2的值。

通常来讲,是可以支持多条三元运算嵌套的,然而在我看来这并不是写代码的良好习惯,可读性太差!

3.2 条件操作符与if语句的对比

条件操作符提供了一种简洁的条件判断方式,它可以替代简单的 if 语句。使用条件操作符可以使代码更加简洁和易读。

下面是一个使用条件操作符的示例:

int age = 18;
char* result = (age >= 18) ? "你是成年人" : "你是未成年";

printf("%s\n", result);

在这个示例中,我们根据年龄的值选择不同的结果。如果年龄大于等于18岁,我们输出"你是成年人";否则,我们输出"你是未成年"。

4. 逻辑操作符

逻辑操作符用于在条件判断中组合多个条件,并根据逻辑关系的真假进行逻辑运算。

4.1 逻辑操作符的种类和用法

C语言中常用的逻辑操作符包括以下几种:

  • &&:逻辑与(AND)
  • ||:逻辑或(OR)
  • !:逻辑非(NOT)

逻辑与操作符(&&)在两个条件都为真时返回真,逻辑或操作符(||)在两个条件中至少一个为真时返回真,逻辑非操作符(!)用于取反。

4.2 逻辑操作符的短路运算特性

逻辑操作符具有短路运算的特性,即在某个条件已经确定的情况下,将不再计算后续的条件。

下面是一个逻辑操作符短路运算的示例:

int num = 10;

if (num > 0 && num < 100) {
    printf("Number is between 0 and 100\n");
}

在这个示例中,如果 num 大于0,才会继续判断 num 是否小于100。如果 num 小于等于0,后续的条件判断将被短路,不再执行。

逻辑与:左假则右不执行,因为一假则假,既然都是假的了,何必浪费时间往右继续判断?

逻辑或:左真则右不执行,因为一真则真,既然都是真的了,那就不用在继续判断啦!

5. switch 语句

现在,让我们来探讨C语言中另一个重要的分支语句:switch 语句。

5.1 switch 语句的基本语法和用法

switch 语句是一种用于多分支选择的语句,它根据表达式的值选择不同的执行路径。

switch 语句的基本语法如下所示:

switch (表达式) {
    case 值1:
        // 执行语句块1
        break;
    case 值2:
        // 执行语句块2
        break;
    ...
    default:
        // 默认执行语句块
        break;
}

在这个语法结构中,表达式的值将与每个 case 的值进行比较,如果匹配,则执行相应的语句块。如果没有匹配的 case,则执行 default 语句块(可选)。

下面是一个使用 switch 语句的示例:

int choice = 2;

switch (choice) {
    case 1:
        printf("You chose option 1\n");
        break;
    case 2:
        printf("You chose option 2\n");
        break;
    case 3:
        printf("You chose option 3\n");
        break;
    default:
        printf("Invalid choice\n");
        break;
}

在这个示例中,根据变量choice的值,我们选择不同的菜单项进行输出。

5.2 switch语句中的执行顺序问题

在 switch 语句中,case 的执行顺序是从上到下的,即匹配到的第一个 case 执行后,会继续执行后续的 case 语句块,直到遇到 break 语句或 switch 语句结束。

如果在 case 语句块中没有使用 break 语句,将会发生case穿透现象,即执行完一个case后,会继续执行下一个case语句块,直到遇到break语句或switch语句结束。

下面是一个"case穿透"的示例:

int num = 2;

switch (num) {
    case 1:
        printf("Number is 1\n");
    case 2:
        printf("Number is 2\n");
    case 3:
        printf("Number is 3\n");
    default:
        printf("Invalid number\n");
}

在这个示例中,如果num的值为2,将会输出"Number is 2"、"Number is 3"和"Invalid number"。这是因为没有在每个case语句块中使用break语句,导致执行顺序继续向下执行。

为了避免case穿透问题,我们可以在每个case语句块的末尾添加break语句,或者使用合适的控制流语句(如if语句)来控制执行流程。

5.3 switch语句的应用场景

switch语句在实际应用中非常常见,特别适用于根据不同的选择执行不同的操作。

例如,在菜单选择、状态机等场景中,我们可以使用switch语句来处理多个固定的选项。

下面是一个使用switch语句的示例:

int choice;

printf("Please enter your choice (1-3): ");
scanf("%d", &choice);

switch (choice) {
    case 1:
        printf("You chose option 1\n");
        break;
    case 2:
        printf("You chose option 2\n");
        break;
    case 3:
        printf("You chose option 3\n");
        break;
    default:
        printf("Invalid choice\n");
        break;
}

在这个示例中,根据用户输入的choice值,我们选择不同的菜单项进行输出。

5.4 switch 语句与 if 语句比较

Switch语句 If语句
用途 多分支选择,适用于固定值的比较 复杂条件判断,适用于灵活的条件逻辑
匹配方式 根据表达式的值与case值进行匹配 根据条件表达式的真假进行匹配
执行顺序 从匹配到的case开始执行,直到遇到break语句或switch结束 从上到下依次执行,根据条件的真假执行相应的代码块
默认执行 可选的default语句块在没有匹配的case时执行 可选的else语句块在条件为假时执行
代码结构 可以将多个选项组织在一起,结构清晰 适用于灵活的条件判断,代码结构较自由
使用场景 处理多个固定选项的选择 处理复杂的条件逻辑,需要灵活的条件判断
示例 根据菜单选项执行不同的操作 根据年龄和性别判断是否满足某个条件