栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

一文带你深入浅出C语言控制语句

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一文带你深入浅出C语言控制语句

目录

前言

1.控制语句总览

2.分支语句

2.1if语句

2.2 例题剖析

2.2.1 例题一 

2.2.2 例题二

2.2.3 例题三

2.3 switch语句

2.4 综合实例

3. 循环语句

 3.1 while语句

3.2 break在while循环中的作用

3.3 continue在while循环中的作用

3.4 一点题外话

3.5 for语句

注意事项

3.6 do...while循环

3.7 循环嵌套

3.8 例题剖析

3.9 二分查找

拓展

3.10 goto语句

题外话

敬请期待更好的作品吧~


前言

        本文主要分享一波个人对C语言控制语句的学习见解与心得,作者水平有限,难免存在纰漏,读者各取所需即可。 

 

给你点赞,加油加油!

 

C语句可分为以下五类:

1. 表达式语句

2. 函数调用语句

3. 控制语句

4. 复合语句

5. 空语句

而本文主要讲讲控制语句。

1.控制语句总览

        控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有九种控制语句。

可分成以下三类:

 1. 条件判断语句也叫分支语句:if语句、switch语句;

 2. 循环执行语句:do while语句、while语句、for语句;

 3. 转向语句:break语句、goto语句、continue语句、return语句。

2.分支语句

2.1if语句

        在C中非零为真,0为假。为什么叫分支语句呢?只要if()括号里的表达式为真,就会执行对应代码,如果还有else语句的话,表达式为假时就不执行if()后面语句,而执行else后面的语句,有点像是如果xxx就xxx不然就xxx,也就像是岔路口多条分支一次只能决定一条分支的路线。

if(exp1)//exp是表达式
{
    //...可以是各种语句
}
else if(exp2)
{
    //...可以是各种语句
}
//...还可以有多个else if语句,相当于树多个分支
else
{
    //...可以是各种语句
}

2.2 例题剖析

2.2.1 例题一 

        为什么啥也不输出呢?

        注意了,if…else…算一条语句,而且else与上面离得最近的if配对,但如果有花括号相隔的话就不一样了。

        即使把缩进改了也没有影响,最多影响自己读程序罢了。

        善用缩进让代码对齐,利于代码的阅读理解,是良好代码风格的体现,不过也要注意单单缩进不会影响程序运行。

2.2.2 例题二

        看看哪一种写法更好一些。

        代码1什么意思呢,如果condition为真就返回1否则返回0,其实执行起来和代码2没区别,但是在读代码的时候可能会觉得是无论if内是否执行最后都要执行return 0;,忽视了return直接结束当前函数的作用。

        其实把return语句换掉就不一样了:

     管你if执不执行都会执行x = 5;。

      所以代码2逻辑更加清晰明了,不需要去估测,是什么就是什么。

2.2.3 例题三

        再看看下面代码,写哪个更好一些?

        按代码3的写法,如果漏写了一个等号,程序有可能照常运行不报错,但是这个错误有可能会影响程序逻辑,产生语义错误(简单来说就是你想的逻辑和你写出来程序的运行逻辑出现差异),关键是编译器不报错找出问题的难度大大增加了,你有可能都不会想到是这一个地方的小问题影响到整个程序的逻辑,费时费力去纠错还不一定能解决问题。

        而按代码4的写法,如果漏写了一个等号,编译器马上就给你报错,一下就找到问题所在,并且可以防微杜渐。莫要到为时晚已积重难返,明明有bug就是找不出来。

        对于代码3和代码4的探讨针对的是左边是不是单个变量,选用代码4风格目的是为防止由逻辑表达式变成赋值表达式,并不是说if()内的条件都要把常数放左边。

        如果待比较的值是常量,可以把该常量放在左侧有助于编译器捕获错误:

        因为C语言不允许给常量赋值,编译器会把赋值运算符的这种用法作为语法错误标记出来,许多经验丰富的程序员在构建比较是否相等的表达式时,都习惯常量放在左侧,还不赶快用起来!

2.3 switch语句

        当switch()括号内的表达式的值满足case时,执行case后面的语句,只要满足就执行,除非遇到break跳出switch(), 可以加上default语句,当所有case不满足时,会执行default语句。

switch(整型表达式)
{  

 语句项;

}

语句项就是一些case语句:

case 整型常量表达式:    

        语句;

比如:

switch(day)
{
    case 1:
        x = 10;
}

        switch必须搭配break才能真正实现分支,没有break的话万一有两个及以上的case满足会把它们后面的语句都执行,压根起不到分支作用。

        如果表达的值与所有的case标签的值都不匹配怎么办?

        其实也没什么,结果就是所有的语句都被跳过而已。

        程序并不会终止,也不会报错,因为这种情况在C中并不认为是个错误。

        但是,如果你并不想忽略不匹配所有标签的表达式的值时该怎么办呢? 你可以在语句列表中增加一条default子句,把下面的标签 default: 写在任何一个 case 标签可以出现的位置。

        当 switch 表达式的值并不匹配所有 case 标签的值时,这个 default 子句后面的语句就会执行。 所以,每个switch语句中只能出现一条default子句。 但是它可以出现在语句列表的任何位置,而且语句流会像执行一个case标签一样执行default子句。

        在每个 switch 语句中都放一条default子句是个好习惯。

有几个要注意的点:

1.switch可以嵌套。

2.case:后面非break语句可以不止一条。

3.break语句在switch一次只能跳出一层switch,而且只能是目前所在的switch。

2.4 综合实例

分析如图

3. 循环语句

 3.1 while语句

        当满足while()括号里的条件也就是括号内表达式为真时,执行while后面语句,直到表达式值为假为止。

while(exp)
{
    //...可以是各种语句
}

3.2 break在while循环中的作用

        其实在循环中只要遇到break,就停止后期的所有的循环,直接终止循环。

        若是有循环嵌套的话break只能跳出一层循环,若是循环里的if语句里的,一样跳出循环。

        所以:while中的break是用于永久终止循环的。

3.3 continue在while循环中的作用

         continue是用于终止本次循环的,也就是本次循环中continue后边的代码不会再执行,而是直接跳转到while语句的判断部分。进行下一次循环的入口判断。

3.4 一点题外话

        遇到这个问题不要慌,因为已经打开了这个可执行程序所以无法再打开,只需要把原先打开的.exe关掉就行。

        好的习惯:声明变量时初始化值。

        

3.5 for语句

         for()语句括号内有三个表达式,分别对应初始化操作,循环判断条件和循环后调整。

for(exp1; exp2; exp3)
{
    //...可以是各种语句

}

        可以发现在while循环中依然存在循环的三个必须条件,但是由于风格的问题使得三个部分很可能偏离较远,这样查找修改就不够集中和方便。

        所以,for循环的风格更胜一筹,for循环使用的频率也最高。

        我们发现在for循环中也可以出现break和continue,他们的意义和在while循环中是一样的。

注意事项

1. 不可在for 循环体内修改循环变量,防止 for 循环失去控制。

2. 建议for语句的循环控制变量的取值采用“前闭后开区间”写法,比如i = 0; i < n;

3.for循环中的初始化部分,判断部分,调整部分是可以省略的,可以省略一个或多个表达式(但是不能省略分号),但是不建议初学时省略,容易导致问题,尤其是判断部分,如果省略的话意味着条件恒成立,会无限循环下去。

4.第一个表达式不一定是给变量赋初值,也可以使用printf()。在执行循环的其他部分之前,只对第一个表达式求值一次或执行一次。

5.for(int i = 0; ; )在初始化部分创建变量并初始化

C99标准才支持,C++也支持。

6.可以使用多于一个变量控制循环

  int x, y;
  for (x = 0, y = 0; x<2 && y<5; ++x, y++)
   {
      printf("hehen");
   }

    

3.6 do...while循环

循环至少执行一次,使用的场景有限,所以不是经常使用。

#include 

int main()
{
     int i = 1;
     do
     {
        if(5 == i)
            continue;
        printf("%dn", i);
        i++;
     }while(i<10);
     return 0;
}

3.7 循环嵌套

        是指在一个循环内包含另外一个或多个循环,在外面的被称为外层循环,在里面的被称为内层循环。

比如:

for(i = 0; i < 4; i++)
{
    for(j = 0; j < 4; j++)
    {
        printf("* ");
    }
    printf("n");
}

        可以分别用来处理行和列的数据。

        for和while以及do...while可以互相嵌套,任意组合。

        要注意的是,内层循环在每次外层循环迭代时都执行完所有的循环,所以嵌套循环的执行次数是内外层循环次数的乘积。

3.8 例题剖析

        看看这个循环怎么样。 

 

        死循环了,一旦i等于5了,就无法再对循环变量进行调整。

        上述代码本来的想法应该是:循环10次,每次循环时如果i==5则打印i的结果。

        但if语句中表达式的==写成了赋值,相当于每次循环尽量都是将i的值设置成了5,5为真,因此每次都会打印5。

        i每次修改成5打印后,i的值永远不会等于10,因此造成死循环。

        结果就是死循环地打印5。

3.9 二分查找

        在查找的时候怎样设计代码比较好?

        比如你在和朋友玩猜数字游戏,他心里想一个一定范围内的数字,假设是0~1000以内,在规定时间内,要你猜一猜,你会怎么猜?当然不可能1,2,3…一点一点猜呀,大家估计都是先对半砍一下——500,不对,小了;那就750,不对还是小了;那825,大了;那……一半一半地砍下去能够很快的缩小查找区间,转眼间就接近目标数字了。

        那在我们设计查找方法的代码的时候就有了二分查找的办法。

int main()
{
    int targ = 0;//查找目标
    int arr[10] = {1, 2, 4, 5, 6, 7, 8, 9, 10, 11};
    int num = sizeof(arr) / sizeof(arr[0]);//数组元素个数

    printf("请输入要查找的元素:n");
    scanf("%d", &targ);
    int left = 0;
    int right = num - 1;
    int mid = 0;

    for (; left <= right;)
    {
         mid = (right - left) / 2 + left;
        if (targ < arr[mid])
        {
            right = mid - 1;
        }
        else if (targ > arr[mid])
        {
            left = mid + 1;
        }
        else
        {
            printf("找到%d了,对应数组下标为:%dn", targ, mid);
            break;
        }
    }
    if (left > right)
    printf("找不到");
    return 0;
}

           注意mid的取值,如果是(left + right) / 2的话,想想看,left+right有没有越界的可能,当数值非常大的时候可能存在溢出,再除于2的话值就不是我们想要的中间值了。那怎么办?

先看看这样一个问题:

        我有两根木棒,把它们立起来,现在我想要“取长补短”,让两木棍一样长,但我不想用(长+短)/2,想想看,还有什么办法没?

看看这个:

        切掉长出来的部分,然后让长出来的部分对半切,再一边一半:

        这下就有办法了:(right - left) / 2 + left。

拓展

关于左右端向中靠拢问题,循环的判断条件一般都是left<=right。

例题:演示多个字符从两端移动,向中间汇聚

比如:################

          w##############!

          we############e!

          wel##########re!

          ......

          welcome to here!

int main()
{
    char a[] = "welcome to here!";
    char b[] = "****************";

    int left = 0;
    int right = strlen(a) - 1;

    for (;left <= right; left++, right--)
    {
        b[left] = a[left];
        b[right] = a[right];
        printf("%sn", b);
    }
    return 0;
}

3.10 goto语句

        C语言中提供了可以随意使用的 goto语句和标记跳转的标号。

        从理论上 goto语句是没有必要的,实践中没有goto语句也可以很容易的写出代码。

        但是某些场合下goto语句还是用得着的,最常见的用法就是终止程序在某些深度嵌套的结构的处理过程。

例如:一次跳出两层或多层循环。 多层循环这种情况使用break是达不到目的的。它只能从最内层循环退出到上一层的循环。

        goto只能在同一个函数内跳转,它无法从一个函数跳转到另一个函数去。

题外话

如何用C语言关机?

使用系统命令:shutdown

在cmd窗口输入shutdown -s -t 60即可设置计算机在60s后关机

输入shutdown -a即可取消该命令


敬请期待更好的作品吧~

感谢观看,你的支持就是对我最大的鼓励,阁下何不成人之美,点赞收藏评论走一波~

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/937916.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号