任务描述
介绍基本语句的组成、使用和各种运算符(算术运算符、关系运算符、逻辑运算符、赋值运算符、逗号运算符等),以及由它们所组成的算术表达式、关系表达式、逻辑表达式、赋值表达式、逗号表达式等。
知识学习
(1)基本语句
在C语言中,其执行部分都是由语句构成的,而程序的功能是由执行这些语句实现的。那么语句有什么特点呢? 像“i=100”这样的是不是语句呢? C语言规定,只有末尾有分号“;”的才算语句,那“i=100”其实只是一个表达式,在其后面加上分号后,才能称为表达式语句。
这里需要注意的是,末尾有分号也不一定全是语句,还需要看其所处的位置,如果出现在数据操作部分,则称为语句。例如“i=100”;或者“x =x +1”。如果出现在数据描述部分的不能算作语句,只能称为数据定义,如“int i;”。
那么在C语言中常见的语句形式有多种:
②表达式语句:语法格式为【表达式;】,如x+y;但是这个无法保留结果,无实际意义。
③函数调用语句:语法格式为【函数名(参数列表);】,如printf(“hello world! \n”);调用函数输出内容到屏幕。
④控制语句:用于控制程序的执行流程,由特定的关键字组成,C语言有9 种控制语句,可分为3 类:
a.条件判断语句:if 语句、switch 语句。
b.循环控制语句:do-while 语句、while 语句、for 语句。
c.跳转语句:break 语句、continue 语句、goto 语句、return 语句。
这部分内容将在下一个项目中讲到。
⑤复合语句:把多个语句用“{}”括起来组成的语句。在程序中可以把这多条语句看作单条语句。例如:
这条复合语句内的各条语句都必须以分号结尾,但在“}”括号外不能加分号。
⑥空语句:只有一个“;”分号,无其他内容。空语句是什么也不执行,可用于完成一个空循环体。
(2)表达式
用运算符将常量、变量等操作对象连接起来,并符合C语言语法规则的式子称为表达式。每个表达式都具有一定的值,也就是运算后的结果,且与具有与结果一致的数据类型。单独表示一个表达式需要加上分号组成程序中的语句,否则语句是不完整的,程序会报错处理。注意:单个常量、变量、函数都可以看作表达式的特例。
根据表达式运算符的种类,可以将C语言中的表达式分为算术表达式、关系表达式、逻辑表达式、赋值表达式、条件表达式、逗号表达式和其他表达式。
以上表达式可以单独存在,也可以根据程序需要组合出现,组成复杂的表达式。例如:
x=(y>0&&y< =9) + z;
从整体上来看,该语句是一个赋值表达式,不过赋值号右侧是由括号内的关系表达式、逻辑表达式及括号外的算术表达式组合而成的。
(3)运算符
运算符是C语言中语句的重要组成部分,由于程序需要对数据进行大量的运算,必须借用运算符来处理。运算符是告诉编译器程序执行什么样运算的符号,它连接各种数据。
运算符主要分为算术运算符、关系运算符、逻辑运算符、赋值运算符和位运算符等。运算符还可以根据参与运算对象的个数分为单目运算符、双目运算符和三目运算符。运算符比较丰富,共有13 类,见表2.6。
表2.6 运算符分类
由该表不难发现,一些运算符有多重含义,比如*可以表示乘运算,也可用于指针运算中;再如&可以用于位运算的与运算,也可以为取地址符。至于具体代表什么意思,要看所处的程序环境决定。
正是C语言丰富的表达式和运算符使得C语言的功能十分完善,本节主要介绍算术、自增、自减、赋值、条件、逗号、逻辑等表达式及其与运算符,其他的表达式和运算符将在后续项目展开介绍。
1)算术表达式和算术运算符
算术表达式是由算术运算符和括号将操作数连接起来且符合C 语法规则的表达式。
先来学习一下基本的算术运算符,见表2.7。
表2.7 算术运算符
这些运算符相互组合在一起,就会出现很多复杂的表达式,在运算时与数学计算一样,有着优先级的问题。如果是读别人的程序需要很好地了解优先级,在C语言所有的运算符中优先级共分15 级,1 级最高,15 级最低,后面将再次介绍。要记住这些优先级确实有点困难,如果是自己书写表达式,当不确定优先级时可以用加括号的方式来表达。
来看这个案例,结果如图2.17所示。
图2.17 算术运算符的优先级
2)自增、自减表达式与自增、自减运算符
自增和自减可以看作特殊的算术运算符,主要有两种写法见表2.8。
表2.8 自增自减
这里对于初学者来说是一个难点,很容易混淆。读者可以这么记忆,不管自增和自减出现在程序中的任何地方,始终遵循这样的原则:++( --)在前,先加(减)后用;++( --)在后,先用后加(减),在运算过程中,使用的永远是表达式的值。如果程序只是为了让变量完成加1或者减1 的效果,两种写法都是一样的。这里还有一点需要注意,该运算符的操作数只能是变量,不能是常量或者表达式。通过下面一个例子来感受一下,运行结果如图2.18所示。
图2.18 自增与自减
本程序中“p=”右边的运算是先计算前两个括号,即5 +6 =11,然后再计算后面的11 +7 =18;“q=”右边的运算也是先运算前面两个括号,但是由于是先加后用的原则,第一个括号j 变成6,第2 个j 变成7,然后在运算时其实j 已经全部为7,所以7 +7 =14,再运算后面的14 +8 =22。
3)赋值表达式和赋值运算符
赋值运算符一般形式为:变量=表达式;如x = i + j ;y =i ++ + --j;,它的运算顺序是从右到左,可以翻译为:把赋值号右边的值赋给左边的变量。凡是有表达式的地方均可出现赋值表达式,是程序语言中出现的频率较高的一个运算符。例如x=(a=3) +(b=7);这是一个合法的语句,先把3 赋给a,再把7 赋给b,然后把两个表达式的值3 和7 相加,结果10 赋给x。
前面在自动类型转换中也提到,当赋值符号左右两边的变量不一致时,右边的类型会被自动转换成左边的类型,注意舍入误差问题。这里说明一下如果是整型数赋给字符数,由于整型所占字节大于字符型所占的字节,此时只给低8 位的值。比如下面的例子,运行结果如图2.19所示。
图2.19 字符与整型的赋值中自动转换
首先a 变量的值322 对应的二进制形式为0001 0100 0010,由于赋给的是字符类型,所以只会把低8 位0100 0010 赋给ch 变量,此时二进制转换成十进制后为66,而66 在ASCII 表中对应的字符为‘B’。
在C语言中,赋值运算符可以跟其他双目运算符组合在一起,构成复合赋值运算符。一般形式为【变量双目运算符= 表达式;】,该表达式等价于【变量= 变量双目运算符表达式;】。
例如:
4)关系表达式与关系运算符
关系运算符是对两个操作对象进行大小的比较,并给出比较的结果,可以看作逻辑运算符的一种简单形式。常用的关系运算符见表2.9。
表2.9 关系运算符
(www.xing528.com)
关系表达式是指用关系运算符连接两个表达式,关系表达式的结果是一个逻辑值,即True 或False,当为True 时,结果用整数1 表示,当为False 时,结果用整数0 表示。
关系表达式的一般形式为【表达式关系运算符表达式】
在上面的代码基础上,再加上一个整型变量z,其值为50。读者可以判断一下表达式z>y>x 的值为多少? 如果这是在数学中,该值一定为真。但是在程序设计中会发现该表达式的结果却是假的。这是因为关系运算符的运算顺序是从左到右,先执行了z >y,此时表达式值为真,结果为1,那么表达式就变成了1 >x 的比较,显然这是不成立的。这里也给读者做了一个警示,如果要表达x 处在某个范围内,是不能按照1 <x <9 方式去写的,因为用户发现不只范围2 ~8 成立,就连9 以上的数据在做判断时表达式也是成立的,要想正确表达该式可以借助逻辑运算符,修改为x>1&&x<9。
5)逻辑运算符与逻辑表达式
逻辑运算用来判断一件事情是否成立,判断的结果只有两个值,用数字1 和0 来表示。其中1 表示逻辑运算结果成立,0 表示逻辑运算结果不成立。逻辑运算符有逻辑与(&&)、逻辑或(||)和逻辑非(!)3 种,逻辑运算符的真值表见表2.10。
表2.10 逻辑关系真值表
由表2.10 可以看出,运算符&&和| |也是双目运算符,从左到右执行。运算符! 为单目运算符,从右向左执行。它们三者的优先级是非最高,次之为逻辑与,最小为逻辑或。
逻辑表达式就是用逻辑运算符把多个表达式连接起来,结果只有两个:0 和1。0 代表假,1 代表真,其一般形式为【表达式逻辑运算符表达式】。由于操作数的值为1 和0,而上节关系表达式的结果也是1 或0,所以这两个运算符经常会组合在一起使用。
在数学中,学过判断某年是否为闰年,需要满足该年份要满足能被4 整除,但不能被100整除,或者能被400 整除。那么借助程序的关系运算符和逻辑运算符可以表达如下:
int year;
year%4 ==0 && year%100! =0 || year%400 ==0;
在逻辑表达式中,有这样一个概念:逻辑短路。这是什么意思呢? 从表2.10 中不难发现,对于逻辑与来说,如果左边的表达式为0,整个表达式的结果一定为0,那么逻辑符号右边的表达式就不会再执行。同理,对于逻辑或来说,如果左边的表达式为1,整个表达式的结果一定为1,那么逻辑符号右边的表达式也不会执行,程序的演示结果如图2.20所示。
图2.20 逻辑短路
从上述程序及结果可以看出,因为逻辑短路的问题,运算符右边的表达式是未执行的,i值始终不变。可以看到逻辑运算符的右侧并不是一个关系表达式,这里也需要读者知道任何非零值都为真。把上面的程序修改一下,运行结果如图2.21所示。
图2.21 非零为真
6)条件表达式与条件运算符
条件运算符是由“?”和“:”组成的,是C语言中唯一的一个三目运算符。用条件运算符连接起来的式子称为条件表达式,语法格式如【表达式1? 表达式2:表达式3】。
执行过程:先计算表达式1 的值,表达式1 为真,则把表达式2 的值作为整个条件表达式的结果;否则把表达式3 的值作为整个条件表达式的结果。
例如:(x> =0)? 1:-1;
该表达式取决于x 的取值,当x 为非负值时,整个表达式结果为1,否则为-1。
条件运算符的结合性为“右结合”,优先级低于算术、关系和逻辑运算符。
例如:x>y? i++:i< =j? i++:++j;
该式等价于x>y ? i++:(i< =j ? i++:++j);
通过一个求两数较大值的例子再来体会一下条件运算符,结果如图2.22所示:
图2.22 条件运算符
7)逗号表达式与逗号运算符
逗号运算符是指运用“,”把若干个表达式连接起来,所组成的表达式称为逗号表达式。该符号的优先级是排在所有运算符的最低位,按照左结合的方式进行。
其一般格式为【表达式1,表达式2,…,表达式n;】,执行过程是先计算表达式1,再计算表达式2,…,最后计算表达式n,并把最后这个表达式的值赋给整个表达式。下面这个例子的运行结果如图2.23所示:
图2.23 逗号运算符
程序先执行d=1 +3 +5(d=9),然后执行3 +5(8),然后执行d++(先用后加),最后把9赋给x,d 变成10。
逗号表达式的写法,从执行顺序的角度可以转换成程序语句方式来进行表达,只是不能获取到相应的值,如【表达式1;表达式2;…;表达式n】
(4)优先级与结合性
C语言的运算符非常丰富,共有34 种,人们为了程序的需要往往把这些运算符组合在一起,那就需要知道这些运算符的优先级以及结合性的问题,这两个问题在C语言中是已经规定好了的。C语言中的运算符总共分为15 级,1 级最高,15 级最低。在表达式中,优先级高者先执行,当优先级相同时,则按照运算符的结合性来处理。表2.11 详细介绍了C语言中运算符的优先级以及结合性问题。
表2.11 优先级与结合性
续表
通过一个简单的例子来演示一下部分运算符之间的混合运算过程,输入三角形的三边,计算出三角形的面积。已知三边分别为a,b,c,则该三角形的面积公式为:
图2.24 运行的结果
如果输入的三边分别为3、4、8,可以看到如图2.25所示结果:
图2.25 错误输入演示
出现如图2.25所示的错误原因是不能保证每次输入的三边能够构成三角形。为了让程序更完整,可以考虑加入对是否构成三角形的判断,同时如果三边不能构成三角形,程序会再次提示用户输入下一组3 条边,构成三角形的条件是任意两边之和大于第三边。
代码如下,程序的运行结果如图2.26所示。
程序执行结果:
图2.26 三角形中的逻辑关系
当三边能构成三角形时表达式a+b>c&&a+c >b&&b +c >a 为真,前面取非后,表达式为假,循环结束;当三边不能构成三角形时表达式a +b >c&&a +c >b&&b +c >a 为假,取非后为真,进入循环体,再次输出新的三边长。
如果看不懂修改后的程序while 循环也没有问题,将在后面深入学习。
任务总结
单目运算符“+ +”和“- -”以及双目运算符“+”和“-”的优先级是相同的,遵从自右向左的结合原则。在本任务中要求掌握各种运算符的运算符特征和运算符之间的优先级,以便在后期编程中灵活使用。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。