zoukankan      html  css  js  c++  java
  • 分支语句

    第四章 分支语句

    1. if语句

    目前我们写的简单函数中可以有多条语句,但这些语句总是从前到后顺序执行的。除了顺序执行之外,有时候我们需要检查一个条件,然后根据检查的结果执行不同的后续代码,在C语言中可以用分支语句(Selection Statement)实现,比如:

     

    其中x != 0表示“x不等于0”的条件,这个表达式称为控制表达式(Controlling Expression)。如果条件成立,则{}中的语句被执行,否则{}中的语句不执行,直接跳到}后面。If和控制表达式改变了程序的控制流程(Control Flow),不再是从前到后顺序执行,而是根据不同的条件执行不同的语句,这种控制流程称为分支(Branch)。

    1. 这里的==表示数学中的相等关系,相当于数学中的=号,在C语言中=号是赋值运算符,两者的含义完全不同。
    2. 如果表达式所表示的比较关系成立则值为真(True),否则为假(False),在C语言中分别用int型的1和0表示。如果变量的值是-1,那么x>0表示这个表达式的值为0,x>-2这个表达式的值为1。
    3. 在数学中a<b<c表示b既大于a又小于c,但作为C语言表达式却不是这样。以上几种运算符都是左结合的。
    4. 这些运算符的两个操作数应该是相同类型的,两边都是整型或者都是浮点型可以做比较,但两个字符串不能做比较。
    5. ==和!=称为相等性运算符(Equality Operator),其余四个称为关系运算符(Relational Operator),相等性运算符的优先等级低于关系运算符。

    在C语言中,任何允许出现的地方既可以是由;号结尾的一条语句,也可以是由{}括起来的若干条语句组成的语句块(Statement Block),如果是语句块则不需要在{}后面再加;号。如果}后面加了;号,则这个;号本身又是一条新的语句了,在C语言中一个单独的;号表示一条空语句。上例的语句块中只有一条语句,也可以简单地写成:

     

    语句块中也可以定义局部变量,例如:

     

    和函数的局部变量同样道理,每次进入语句块时为变量j分配存储空间,每次退出语句块时释放变量j的存储空间。语句块中的变量i和函数的局部变量i是两个不同的变量,因此两次打印的i值是不同的;语句块中的变量j在退出语句块之后就没有了,因此最后一行的printf不能打印变量j,否则编译器会报错。语句块可以在任何允许出现语句的地方,不一定非得用在if语句中,单独使用语句块通常是为了定义一些比的局部变量更“局部”的变量。

    2.if/else语句

             If语句还可以带一个else子句(Clause),例如:

     

    这里的%是取模(Model)运算符,x%2表示x除以2所得的玉树(Remainder),%运算符的两个操作数必须是整型的。如果/运算符的两个操作数都是整型的,则结果是两个数的商(Quotient),余数总是被截掉,因此有如下结论:a和b是整型的,b不等于0,则(a/b)*b+a%b总是等于a。上例判断x的奇偶性(Parity),为了重复使用,可以把它封装(Encapsulate)成一个函数:

     

    把语句封装成函数的基本步骤是:把语句放到函数体中,把变量改成函数的参数。这样,以后要检查一个数的奇偶性只需调用这个函数而不必重复写这条语句,例如:

     

    If/else语句的语法规则如下:

             语句——>(控制表达式)语句else语句

    右边的“语句”既可以是一条语句,也可以是由{}括起来的语句块。一条if语句中包含一条子语句,一条if/else语句中包含两条子语句,子语句可以是任何语句或语句块,当然也可以是另外一条if或if/else语句。根据组合规则,if或if/else可以嵌套使用。

     

    也可以这样:

     

             现在有一个问题,类似if(A) if(B) C; else D; 形式的语句理解方式是不同的,可以是:

     

    也可以是:

     

             C代码的缩进只是为了程序员看起来方便,但实际上对编译器不起任何作用,你的代码不管写成上面的哪一种缩进格式,在编译器看起来都是一样的。那么else到底是和if(A)配对还是和if(B)配对?很多编程语言的语法都有这个问题,称为Dangling-else问题。C语言规定,else总是和它上面最近的一个if配对,因此应该理解成else和if(B)配对,也就是按第二种方式理解。如果你写成上面第一种缩进的格式就很危险了:你看到的是这样,而编译器理解的确是那样。如果你希望编译器按第一种方式理解,应该明确加上{}:

     

             顺便提一下,浮点型的精度有限,不适合使用==运算符做精确比较。以下代码可以说明问题:

     

    不同的平台的浮点数实现有很多不同之处,在我们的平台上运行这段程序结果为Unequal,即使在你的平台上运行的结果为Equal,你再把i改成其他值试试,总会有些值会使得结果为Unequal。

    3.布尔代数

    在C语言中,逻辑与(Logical AND)运算符表示两个条件同时成立,写成两个&号(Ampersand),

    逻辑或(Logical OR)运算符,写成两个|线(Pipe Sign),逻辑非(Logical NOT)运算符,写一个!号(Exclamation Mark)。

             逻辑或表示两个条件只要有一个为真,它们做逻辑或运算的结果就为真,只有两个条件都为假,逻辑或运算的结果才为假。逻辑非的作用是对原来的逻辑值取反,原来是真的就是假,原来是假的就是真。逻辑运算符只有一个操作数称为单目运算符(Unary Operator),以前的加减乘除、赋值、相等性、关系、逻辑与、逻辑或运算符都有两个操作数,称为双目运算符(Binary Operator)。

             运算符的优先级顺序是:!高于*/%,高于+-,高于>< >= <=,高于== !=,高于&&,高于||。写一个控制表达式很可能同时用到这些用算符中的多个,如果记不清运算符的优先等级一定要多套括号。

    4.switch语句

    Switch语句可以生产具有多个分支的控制流程。它的格式是:

     

    如果传入的参数是n,则从case n分支开始执行,先是打印相应的信息,然后遇到break语句,它的作用是跳出整个switch语句块。C语言规定各case分支的常量表达式必须互不相同,如果控制表达式不等于任何一个常量表达式,则从default分支开始执行,通常把default分支写在最后,但不是必须的。

    使用switch语句要注意几点:

    1) case后面跟表达式的必须是常量表达式,这个值和全局变量的初始值一样必须在编译时计算出来。

    2) 由于浮点型不适合做精确比较,所以C语言规定case后面跟的常量表达式必须是整型的。

    3) 进入case后如果没有遇到break语句就会一直往下执行,后面其他case或default分支的语句也会被执行到,直到遇到break,或者执行到整个switch语句块的末尾。通常每个case后面都要加上break语句,但有时会故意不加break来利用这个特性,例如:

     

    Switch语句不是必不可缺的,显然可以用一组if . . . else if . . . else if . . . else . . . 代替,但是一方面用switch语句会使代码更清晰,另一方面,有时候编译器会对switch语句进行整体优化,使它比等价的if/else语句所生成的指令效率更高。

  • 相关阅读:
    响应式布局
    Fiddler2汉化版使用说明
    nonmember,nonfriend替换member函数
    Java回顾之Spring基础
    dudu,想在cnblogs首页看很久以前的文章不行。
    基于Nios II内核的项目程序为什么越优化越慢?
    学习 easyui:禁用 linkbutton 问题
    Socket编程 (异步通讯,解决Tcp粘包) 3
    .NET:可扩展的单据编号生成器 之 基于缓冲区的顺序号
    淘宝API应用开发
  • 原文地址:https://www.cnblogs.com/exew/p/8109129.html
Copyright © 2011-2022 走看看