C语言中的循环和分支语句(最全攻略!!)

目录

一、整体介绍

二、分支语句

1. if-else语句

1.1 基本语法

1.2 嵌套和多条件

2. switch语句

2.1 基本语法

2.2 注意事项

三、循环语句

1.1 基本语法

1.2 循环控制语句

2. while循环和do-while循环

2.1 while循环

2.2 do-while循环

3、使用循环语句需要的注意事项

3.1 循环终止条件

3.2 循环变量的初始化和更新

3.3 避免死循环

3.4 控制语句的正确使用

3.5 循环嵌套

3.6 数组越界

3.7 逻辑错误和初始化问题

3.8 循环和函数

3.9 优化循环

四、完结撒花

一、整体介绍

        在C语言中,语句(statement)是构成程序的基本单位,是一条指令或命令,用于执行特定的操作。每个语句通常以分号(;)结尾。C语言中有多种类型的语句,其中一些主要的类型包括:

1、赋值语句(Assignment Statement): 赋值语句用于给变量赋值。例如:x = 10;

2、条件语句(Conditional Statement): 条件语句根据条件来执行特定的代码块。最常见的是if-else语句。例如:

if (condition) 
{
    // do something
} 
else 
{
    // do something else
}

3、循环语句(Loop Statement): 循环语句用于重复执行特定的代码块,直到满足特定条件为止。常见的有forwhiledo-while循环。

4、函数调用语句(Function Call Statement): 函数调用语句用于调用函数并执行其中的代码。例如:

functionName(argument1, argument2);

5、空语句(Null Statement): 空语句只有一个分号,用于表明一个空操作。例如:

;

6、复合语句(Compound Statement): 复合语句是由多条语句组成的块,通常使用大括号{}括起来。例如:

{
    // multiple statements
    int a = 10;
    printf("%d", a);
}

这些语句组成了C语言程序的逻辑结构,通过这些语句的组合和嵌套,可以实现复杂的功能和逻辑。

二、分支语句

当谈及C语言中的分支语句时,这是程序设计中至关重要的概念之一。分支语句允许程序根据条件选择性地执行不同的代码块。下面讲介绍if-else语句与switch语句的用法

1. if-else语句

1.1 基本语法

if-else语句用于根据条件执行不同的代码块。

if (条件) 
{
    // 如果条件为真,执行这里的代码
}
else 
{
    // 如果条件为假,执行这里的代码
}
1.2 嵌套和多条件

if-else语句可以嵌套使用,也可以通过逻辑运算符组合多个条件,实现更复杂的逻辑。

if (条件1) 
{
    // 如果满足条件1,执行这里的代码
}
else if(条件2)
{
    //如果满足条件2,执行这里的代码
}

// …………

else if(条件n)
{
    //如果满足条件n,执行这里的语句
}
else
{
    //如果上述条件都不满足,执行这里的语句
}

2. switch语句

2.1 基本语法

switch语句根据表达式的值执行匹配的case代码块。

switch (表达式) 
{
    case 表达式的值1:
        // 如果表达式等于值1,执行这里的代码
        break;
    case 表达式的值2:
        // 如果表达式等于值2,执行这里的代码
        break;
    // 可以有更多的case
    default:
        // 如果表达式与所有case都不匹配,执行这里的代码
        break;
}
2.2 注意事项

switch语句中的break语句很重要,它用于跳出switch代码块。同时,default分支可处理未匹配到任何case的情况。

注意:每次case之后必须要有break跳出分支语句,如果没有break,程序则会自上而下进行,执行下面的语句,根据这种规则,我们可以巧妙地写出当满足多个值时共同执行同一处代码的例子,例如:

#include <stdio.h>

int main()
{
    int input = 0;
    scanf("%d", &input);

    switch(input)
    {
        case 1:
        case 2:
        case 3:
            //输入1或2或3时想要执行的代码
            break;
        case (其他值):
            //代码
            break;
        default :
            //代码
            break;
    }

    return 0;
}

三、循环语句

1.1 基本语法

for循环用于执行已知次数的循环操作。

for (初始化; 条件; 更新) 
{
    // 在条件为真时执行的代码块
}
1.2 循环控制语句

for循环常用的控制语句包括breakcontinue,分别用于跳出循环和跳过当前循环的剩余部分。

例如:

#include <stdio.h>

int main() 
{
    // 示例1:使用 break 跳出循环
    printf("示例1:使用 break 跳出循环\n");
    for (int i = 1; i <= 5; i++) 
    {
        printf("%d ", i);
        if (i == 3) 
        {
            break; // 当 i 等于 3 时跳出循环
        }
    }
    printf("\n");

    // 示例2:使用 continue 跳过当前循环的剩余部分
    printf("\n示例2:使用 continue 跳过当前循环的剩余部分\n");
    for (int j = 1; j <= 5; j++) 
    {
        if (j == 3 || j == 4) 
        {
            continue; // 当 j 等于 3 或 4 时跳过当前循环的剩余部分
        }
        printf("%d ", j);
    }
    printf("\n");

    return 0;
}

示例1展示了使用break语句在for循环中的应用。当i等于3时,break语句使程序立即跳出循环,不再执行后续循环。

示例2展示了使用continue语句在for循环中的应用。当j等于3或4时,continue语句使程序跳过当前循环的剩余部分,直接进入下一轮循环。

2. while循环和do-while循环

2.1 while循环

while循环在条件为真时重复执行代码块。

while (条件) 
{
    // 在条件为真时执行的代码块
}
2.2 do-while循环

do-while循环会先执行一次代码块,然后检查条件是否为真,如果为真则继续执行。

do 
{
    // 至少执行一次的代码块
} while (条件);

也就是说while循环是先要进行条件判断的循环,而do-while循环是不管三七二十一上来先循环一次,后续再进行条件判断来确定是否要循环下一次的循环

3、使用循环语句需要的注意事项

3.1 循环终止条件

确保循环有正确的终止条件,否则可能陷入无限循环(死循环),导致程序永远无法结束。比如,在使用whilefor循环时,检查循环条件是否能在某个点上变为假值。

#include <stdio.h>

int main()  
{
        int count = 0;

        while (count < 5) 
    {
        printf("Count: %d\n", count);
        // 此处意外地忘记增加count变量的值
        // 如果没有适当的增加count的值,循环条件永远为真,导致无限循环
    }

    printf("Loop ended!\n");

    return 0;
}

在这个例子中,while循环的终止条件是count < 5,但循环体内忘记了增加count的值,这会导致count永远保持小于5的状态,因此循环条件永远为真,程序无法跳出循环。

为了避免这种情况,应该在适当的地方更新循环控制变量,确保最终循环条件会变为假,从而退出循环。修复上面的代码可以这样做:

#include <stdio.h>

int main() 
{
    int count = 0;

    while (count < 5) 
    {
        printf("Count: %d\n", count);
        count++; // 增加count的值,确保最终循环条件变为假
    }

    printf("Loop ended!\n");

    return 0;
}

3.2 循环变量的初始化和更新

在使用for循环时,确保循环变量在进入循环前被正确初始化,并在循环体内正确更新,以免造成意外的循环行为或无限循环。

#include <stdio.h>

int main() 
{
    // 示例1:循环变量未正确初始化
    printf("示例1:循环变量未正确初始化\n");
    int i;
    for (i = 5; i >= 0; i--) 
    {
        printf("%d ", i);
    }
    printf("\n");

    // 示例2:循环变量未正确更新
    printf("\n示例2:循环变量未正确更新\n");
    for (int j = 0; j < 5; /* 此处未更新循环变量 */) 
    {
        printf("%d ", j);
        // 更新循环变量的语句缺失
    }
    printf("\n");

    return 0;
}

在示例1中,循环变量i并没有在进入循环前被正确初始化,导致循环的起始值是未知的。在这种情况下,循环可能会产生意外的结果。

在示例2中,循环变量j虽然被正确初始化,但在循环中缺少了更新循环变量的语句,这将导致循环变量始终保持在初始值,进而导致无限循环或不符合预期的循环行为。

修复这些问题的方式是确保循环变量在进入循环前被正确初始化,并在循环体内正确更新。例如:

#include <stdio.h>

int main() 
{
    // 示例1修复:正确初始化循环变量
    printf("示例1修复:正确初始化循环变量\n");
    int i;
    for (i = 5; i >= 0; i--) 
    {
        printf("%d ", i);
    }
    printf("\n");

    // 示例2修复:正确更新循环变量
    printf("\n示例2修复:正确更新循环变量\n");
    for (int j = 0; j < 5; j++) 
    {
        printf("%d ", j);
    }
    printf("\n");

    return 0;
}

3.3 避免死循环

小心编写循环条件,确保循环能够正常结束。在开发过程中,尽量避免无意义的或永远为真的循环条件,这样可以防止出现意外的程序行为。

#include <stdio.h>

int main() 
{
    // 示例:无限循环
    printf("示例:无限循环\n");
    int i = 5;
    while (i > 0) 
    {
        printf("%d ", i);
        // 错误的更新循环变量,导致循环条件永远为真
        // 正确的更新应该让循环条件最终变为假,以结束循环
        i++;
    }

    return 0;
}

在这个例子中,while循环的条件是i > 0,但在循环体内,错误地更新了i的值,使其增加而不是减少。因此,i永远不会小于等于0,循环条件永远为真,导致了无限循环。

为了避免死循环,需要确保循环条件最终可以变为假,以使循环能够正常结束。修复上述代码可以这样做:

#include <stdio.h>

int main() 
{
    // 示例修复:避免无限循环
    printf("示例修复:避免无限循环\n");
    int i = 5;
    while (i > 0) 
    {
        printf("%d ", i);
        i--; // 正确地更新循环变量,确保循环条件最终为假
    }

    return 0;
}

3.4 控制语句的正确使用

breakcontinue是循环中的控制语句,但滥用它们可能导致程序逻辑变得难以理解。谨慎使用这些语句,确保它们用于合适的情景。

#include <stdio.h>

int main() 
{
    // 示例:滥用控制语句
    printf("示例:滥用控制语句\n");
    for (int i = 1; i <= 5; i++) 
    {
        if (i == 2 || i == 4) 
        {
            continue; // 遇到 i 为 2 或 4 时跳过当前迭代
        }
        printf("%d ", i);
        if (i == 3) 
        {
            break; // 当 i 等于 3 时跳出循环
        }
    }
    printf("\n");

    return 0;
}

在这个示例中,continue语句用于跳过循环中的特定迭代,而break语句用于在特定条件下跳出整个循环。这种使用方式可能会使程序逻辑变得复杂和难以理解。

修复这个问题的方式是通过精简和清晰地控制程序流程,避免过度依赖breakcontinue语句。下面是修复后的示例:

#include <stdio.h>

int main() 
{
    // 示例修复:避免滥用控制语句
    printf("示例修复:避免滥用控制语句\n");
    for (int i = 1; i <= 5; i++) 
    {
        if (i != 2 && i != 4) 
        {
            printf("%d ", i);
        }
        if (i == 3) 
        {
            break; // 当 i 等于 3 时跳出循环
        }
    }
    printf("\n");

    return 0;
}

3.5 循环嵌套

循环嵌套可以实现复杂的逻辑,但也容易使代码变得复杂难懂。当使用嵌套循环时,确保代码结构清晰,尽量避免过度嵌套。

#include <stdio.h>

int main() 
{
    // 示例:过度嵌套循环
    printf("示例:过度嵌套循环\n");
    for (int i = 1; i <= 3; i++) 
    {
        for (int j = 1; j <= 3; j++) 
        {
            for (int k = 1; k <= 3; k++) 
            {
                printf("%d %d %d\n", i, j, k);
            }
        }
    }

    return 0;
}

在这个示例中,三重嵌套循环会生成 3x3x3 共27次迭代的输出。尽管它可以正常工作,但随着嵌套层数的增加,代码变得更加复杂,不易理解。

为了使代码更易读和维护,可以考虑将嵌套循环中的逻辑提取为函数或模块,或者重新考虑解决问题的方式,以减少循环的层数。下面是一个简化并改善可读性的示例:

#include <stdio.h>

void printValues(int i, int j, int k) 
{
    printf("%d %d %d\n", i, j, k);
}

int main() 
{
    // 示例修复:减少嵌套循环层数
    printf("示例修复:减少嵌套循环层数\n");
    for (int i = 1; i <= 3; i++) 
    {
        for (int j = 1; j <= 3; j++) 
        {
            for (int k = 1; k <= 3; k++) 
            {
                printValues(i, j, k);
            }
        }
    }

    return 0;
}

在修复后的代码中,虽然仍然有嵌套循环,但通过将打印逻辑提取为一个函数printValues,并通过函数的方式减少了嵌套循环的可读性问题。这样可以使代码更易于理解和维护。

3.6 数组越界

在使用循环遍历数组时,务必确保不要越界访问数组元素,这可能导致程序崩溃或产生不可预知的结果。

#include <stdio.h>

int main() 
{
    int array[5] = {1, 2, 3, 4, 5};

    // 示例:可能导致数组越界的循环
    printf("示例:可能导致数组越界的循环\n");
    for (int i = 0; i <= 5; i++) 
    {
        printf("%d ", array[i]);
    }
    printf("\n");

    return 0;
}

在这个示例中,for循环的循环条件是i <= 5,但数组array的长度是5,下标范围只能是0到4。因此,当i等于5时,array[5]就会越界访问数组,导致不可预知的行为。

为了避免数组越界问题,需要确保循环索引在数组索引的有效范围内。修复这个问题的方式是修改循环条件,确保不会越界访问数组:

#include <stdio.h>

int main() 
{
    int array[5] = {1, 2, 3, 4, 5};

    // 示例修复:避免数组越界
    printf("示例修复:避免数组越界\n");
    for (int i = 0; i < 5; i++) 
    {
        printf("%d ", array[i]);
    }
    printf("\n");

    return 0;
}

3.7 逻辑错误和初始化问题

检查循环内的逻辑,特别是在使用whiledo-while时,确保循环条件正确,并检查循环变量的初始化是否准确。

#include <stdio.h>

int main() 
{
    int i = 5;

    // 示例:逻辑错误和初始化问题
    printf("示例:逻辑错误和初始化问题\n");
    while (i > 0) 
    {
        printf("%d ", i);
        i--; // 错误的更新循环变量位置
    }
    printf("\n");

    return 0;
}

在这个示例中,while循环的终止条件是i > 0,并且在循环体内i被递减。但i--操作放置在了循环体内的最后,这会导致在打印i之后再递减i的值。结果是循环将打印出 5,但之后会陷入无限循环,因为i永远不会小于等于0。

修复这个问题的方式是将循环变量的更新放在循环体内的正确位置:

#include <stdio.h>

int main() 
{
    int i = 5;

    // 示例修复:修正逻辑错误和初始化问题
    printf("示例修复:修正逻辑错误和初始化问题\n");
    while (i > 0) 
    {
        printf("%d ", i);
        i--; // 正确的更新循环变量位置
    }
    printf("\n");

    return 0;
}

3.8 循环和函数

在循环中调用函数时,注意函数对循环行为的影响。特别是在递归函数中,可能会影响循环的层数和性能。

#include <stdio.h>

// 递归函数示例
int recursiveFunction(int n) 
{
    if (n <= 0) 
    {
        return 0;
    }
    printf("%d ", n);
    return recursiveFunction(n - 1);
}

int main() 
{
    // 示例:递归函数在循环中的影响
    printf("示例:递归函数在循环中的影响\n");
    for (int i = 5; i > 0; i--) 
    {
        recursiveFunction(i);
        printf("\n");
    }

    return 0;
}

在这个示例中,recursiveFunction是一个递归函数,用于打印从n到1的数字。在main函数的循环中,我们调用了recursiveFunction来打印数字。

然而,当递归函数被嵌套在循环内调用时,它的递归深度受循环迭代次数的影响。在实际应用中,特别是在大规模的循环中,递归深度可能会变得非常大,可能导致栈溢出或性能下降的问题。

为了避免这种情况,可以重新考虑循环内是否需要递归调用函数,或者尝试优化递归函数以减少其对内存和性能的影响。如果必须在循环内调用递归函数,需要特别小心地管理递归深度,以避免出现不必要的问题。

3.9 优化循环

对于大型循环,考虑如何优化以提高程序的性能,比如减少不必要的循环迭代或使用更高效的算法。

#include <stdio.h>

int main() 
{
    // 示例:优化循环以减少不必要的迭代
    printf("示例:优化循环以减少不必要的迭代\n");
    int sum = 0;
    for (int i = 1; i <= 100; i++) 
    {
        if (i % 2 == 0) 
        {
            sum += i;
        }
    }
    printf("偶数的和为:%d\n", sum);

    return 0;
}

在这个示例中,我们计算了1到100之间所有偶数的和。然而,实际上只有每隔一个数是偶数,因此可以优化循环来减少迭代次数,提高效率:

#include <stdio.h>

int main() 
{
    // 示例修复:优化循环以减少不必要的迭代
    printf("示例修复:优化循环以减少不必要的迭代\n");
    int sum = 0;
    for (int i = 2; i <= 100; i += 2) 
    {
        sum += i;
    }
    printf("偶数的和为:%d\n", sum);

    return 0;
}

 在修复后的代码中,我们将循环的初始值设为2,并每次增加2,这样就直接从第一个偶数开始,避免了检查每一个数字是否为偶数的操作,减少了循环的迭代次数,提高了效率。

四、完结撒花

学习C语言是通向计算机编程世界的一扇大门,它不仅让你深入了解计算机底层原理,还能锻炼逻辑思维和问题解决能力。掌握C语言不仅能让你编写高效的程序,还能为你未来学习其他编程语言打下坚实基础。无论是想要成为软件开发工程师、嵌入式系统设计者还是深入研究计算机科学的学者,学习C语言都是非常有价值的。坚持学习,不断实践,相信你会在这条编程的道路上获得更多的收获和成就!

  • 21
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RedefineLim.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值