运算符与表达式

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图1-1 算术运算过程的转换规则 (1)横向向左的箭头,表示必须的转换。在参加运算的数据中,如果有 char 和 short 型数据则必须先转 换成 int 型数据才能参与运算,同样的情况,float 型必须转换成 double 型才能参加运算。 (2)纵向向上的箭头,表示不同类型的转换方向。在参加运算的数据中,如果出现了不同类型的数据, 则要按照所有参与运算的数据的按照箭头所指方向的数据类型最高的级别进行转换。 例如,当有 int 型与 double 型数据进行混合运算,则先将 int 型数据转换成 double 型,然后在两个同类型 的数据间进行运算, 结果为 double 型。
2
分为右结合(从右向左)和左结合(从左到右)两种方式。具体的结合性见附录。
3.3表达式
表达式是由常量、变量、函数等通过运算符连接起来而形成的一个有意义的算式。特别地:一个常量、一 个变量、一个函数都可以看成是一个表达式。一个表达式代表着一个具有特定数据类型的具体值。 与运算符连接的常量、变量、函数等组成了 C 语言表达式,C 语言的表达式有:算术表达式、赋值表达式、 关系表达式、逻辑表达式、条件表达式、逗号表达式和指针表达式等。表达式的运算主要按照运算符的优先级 和结合性所规定的顺序进行, 其次还要考虑与运算的操作数是否具有相同的数据类型以及是否需要进行类型转 换,每个表达式代表着一个确定的值和确定的数据类型。 表达式的求值计算过程实际上是一个数据加工的过程,通过各种不同的运算符可以实现不同的数据加工。 表达式代表了一个具体的值,在计算这个值时,要根据表达式中各个运算符的优先级和结合性,按照优先级高 低,从高到低地进行表达式的运算,对同级的优先级则要按照该运算符的结合方向按从左向右或从右向左的顺 序计算,否则很容易得到错误的结果。同时,为了改变运算次序,可以采用小括号()方式,因为小括号() 的优先级最高,以此提升某个运算次序。 在表达式中运算符连接运算量完成了数据处理,这个数据处理的结果通常要做进一步的应用,因此必须知 道表达式运算结果的数据类型。在表达式完成运算的过程中,如果是不同类型间数据的混合运算,应该遵循数 据类型自动转换的规则,表达式的数据类型是所有参与运算的运算量的最高的数据类型。 读者在以前接触过代数表达式,对比 C 语言的表达式,可以看到有下面几个方面的区别: (1)不是所有的代数运算符都被 C 语言支持,有些代数运算符在 C 语言里是没有的。例如:∫ √ ≈ ㏒ 等。 (2)使用表达式时要注意运算符的书写格式,和代数运算符相比,一个功能相同的运算符在书写形式上 是有区别的。例如:在 C 语言中,用‘*’表示乘法,以区别乘号(x)与英文字母 x;除号用‘/’表示; (3)在 C 语言中,所有表达式都要必须写在一行上,例如:a/b,不允许写成普通的数学算式(分上、下 行); (4)有些代数运算符在 C 语言中是用函数或其它形式实现的。例如:幂运算或者采用连乘的方式实现, 例如:x3 应改写成 x*x*x,或者调用数学库函数实现。对于数学上的函数(例如:求平方根、求 sin 值等)可 以采用调用数学库函数的形式计算其结果值。 (5)在 C 语言中还有一些在代数运算符中没有的运算符。例如:?运算符、->运算符等。
我们通过下面的例子区分一下: (1)若有 int i=3, j; j=++i; 表达式运算结束后,则 i=4, j=4。 其执行过程为:先将 i 的值自加 1,i 值变为 4,再使用此时 i 的值赋给 j。 (2)而对于 int i=3, j; j=i++; 表达式运算结束后,则:i=4,j=3。 执行过程:先使用 i 的值 3,将 3 赋给 j,这之后 i 再自加 1,变为 4。 【例3-1】阅读程序。
3.4.3算术运算符的优先级与结合性
在进行代数运算中,我们都记得:先乘除,后加减,有括号先计算括号里面。这就是代数运算的优先级问 题。在计算 C 语言的表达式的值时,同样要按照运算符的优先级由高到低依次执行。 C 语言中,运算符的运算优先级共分为 15 级。1 级最高,15 级最低。 在表达式中,优先级较高的先于 优先级较低的进行运算。而在一个运算量两侧的运算符 优先级相同时,则按运算符的结合性所规定的结合方 向处理。 例如:算术运算符的优先级是“先乘除、后加减”。如:a+b*2,那么就要先计算乘法再计算加法,相当 于 a+(b*2)。 如果一个运算量两侧的运算符的优先级相同,如 a+b-2,则按照结合方向处理。 和代数运算不同,C 语言中的运算符不但有优先级的问题,而且还有结合性的问题。C 语言中各运算符的 结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。例如:算术运算符的结合性是自左至右,即 先左后右。如有表达式 x-y+z 则 y 应先与“-”号结合,执行 x-y 运算,然后再执行+z 的运算。这种自左至右 的结合方向就称为“左结合性”。而自右至左的结合方向称为“右结合性”。最典型的右结合性运算符是赋值运 算符。如 x=y=z,由于“=”的右结合性,应先执行 y=z 再执行 x=(y=z) 运算。C 语言运算符中有不少为右结合 性,应注意区别,以避免理解错误。 【提示3-4】 当+、-作为正值/负值运算符时,可看作单目运算符。例如:+2(+可省略)、-2 等。
第 3 章 运算符与表达式
【本章要点】 z C 语言有哪些表达式?各种表达式的求解规则是如何规定的? z 什么是 C 语言运算符的优先级和结合性? z 表达式运算结果的数据类型是如何确定的? 在上一章中我们知道了必须用多种不同类型的数据来描述一个人的相关信息,但在这些信息中,我们不能 判断某人的性别和学历是否相等,同样的,也不能用一个人的身高和另一个人的年龄相加减。并不是说这样的 运算是被禁止的,只是这种运算的结果毫无意义。所谓定义数据类型,就是把这些数据分类,并界定范围,使 得数据之间的运算有意义,得出我们所需要的结果。
3.2运算符
C 语言提供了大量的运算符,这些运算符可以进行数据的运算处理,这是 C 语言的主要特点之一。它们从 功能上可以分为:算术运算符、赋值运算符、关系运算符、逻辑运算符等;从运算对象上可以分为:单目运算 符、双目运算符和三目运算符。运算符具有优先级和结合性。结合性是 C 语言独有的特点。 运算是对数据进行操作、处理的过程,是通过运算表达式描述的,运算表达式是由“运算符+运算量”组 成的。其中,运算符表示对数据进行何种处理,如加减乘除等;而被处理的数据称作运算量。 C 语言有很多种运算符,请参看附录的“运算符优先级与结合性”表。对于一个运算符,应从以下四个方 面理解: (1)运算符的意义:不同的运算符代表了能够处理不同的操作。 (2)和操作符相关的数据类型:不同的运算符对参与运算的数据类型要求不同,运算符的运算结果的数 据类型也不相同。 (3)运算符的优先级:表示不同运算符参与运算时的先后顺序,优先级高的先于优先级低的运算符进行 运算。具体的优先级别排列见附录。 (4)运算符的结合性:当优先级相同的时候,按照运算符的结合方向确定运算的次序,运算符的结合性
3.4.2自增运算符和自减运算符
自增运算符+ +、自减运算符--的作用是:让变量自己加 1 或者减 1,它们经常用在循环结构中,控制循环 变量的变化。要注意的是,这两种运算符都有前置和后置之分。
表 3-1 自增自减运算符 名称 增 1(前缀) 增 1(后缀) 减 1(前缀) 减 1(后缀) 运算符 ++ ++ --例 ++i i++ --i i-说明 先将 i 的值加 1,再使用此时 i 的值。 先使用 i 的值,再将 i 的值加 1。 先将 i 的值减 1,再使用此时 i 的值。 先使用 i 的值,再将 i 的值减 1。
#include<stdio.h> void main() { int i=8; printf("%d\n",++i); printf("%d\n",--i); printf("%d\n",i++); printf("%d\n",i--); printf("%d\n",-i++); printf("%d\n",-i--); } 程序运行的结果是: 9 8 8 9 -8 -9
1
Biblioteka Baidu
不要理解为 int 型先转换成 unsigned 型, 再转换成 long 【提示3-1】 箭头方向只表示数据类型由低向高转换, 型,最后转换成 double 型。
2. 强制类型转换
如果程序要求一定将某一类型的数据从该种类型强制地转换为另外一种类型, 则需要人工编程进行强制类 型转换,也称为显式转换。强制类型转换的目地是使获得的数据类型发生改变,从而使不同类型的数据之间的 运算能够进行下去。 强制类型转换的语法格式如下: (类型说明符) (表达式) ; 当被转换的表达式是一个简单表达式时,外面的一对圆括号可以缺省。 例如: int a; float x,y;double l; l= (double)a 等价于(double)(a) /*将变量 a 的值转换成 double 型*/ a= (int)(x + y) /*将 x+y 的结果转换成 int 型*/ (float)5 / 2 等价于(float)(5)/2 /*将 5 转换成实型,再除以 2(=2.5)*/ (float)(5 / 2) /*将 5 整除 2 的结果(2)转换成实型(2.0)*/ 强制转换时,类型符要用括号括起来。强制类型转换只是要获得一个要求的数据类型的数值,并不是改变 数据的类型,强制转换后,变量仍保持原来的类型。变量在定义的时候已经指定了数据类型,在程序运行的过 程中,变量的数据类型是不能改变的。如上例中 a 仍为整型,x、y 仍为 float 型。 需要注意的是,这种转换带来的后果是不能得到精确的值,如果需要不同类型的结果,最好使用专用函数 来进行转换。 【提示3-2】 强制转换类型得到的是一个所需类型的中间量,原表达式类型并不发生变化。例如,(double)a 只是将变量 a 的值转换成一个 double 型的中间量,其数据类型并未转换成 double 型。
3.4.4算术表达式
在使用自增/自减运算示应注意下面几个问题: (1)自增/自减只能作用于变量,不允许对常量、表达式或其它类型的变量进行操作。例如--5 或者(a+b)++ 都是不合法的。
4
(2)当变量出现在表达式中,前缀运算和后缀运算的结果有差别。但当自增或自减变量值的运算本身就 单独构成一条语句时,把自增或自减运算符放在变量前或放在变量后的效果是一样的。即++n;等价于 n++; --n;等价于 n--;
3.1数据类型转换
不同数据类型的数据可以相互转换。这种转换可能发生在算术表达式、赋值表达式和输出时。转换的方式 有两种:自动转换和强制转换。
1. 自动转换
在C语言中,整型、实型和字符型数据间可以混合运算(因为字符数据与整型数据可以通用)。 如果一 个运算符两侧的操作数的数据类型不同,则系统按“先转换、后运算”的原则,首先将数据自动转换成同一类 型 ,然后在同一类型数据间进行运算。转换规则如图 1 所示。
//i 的值先加 1,i 的值变为 9,然后再输出 //i 的值先减 1,i 的值变为 8,然后再输出 //i 的值先输出,然后加 1,i 的值变为 9 //i 的值先输出,然后减 1,i 的值变为 8 //先输出-1*i 的值,然后加 1,i 的值变为 9 //先输出-1*i 的值,然后减 1,i 的值变为 8
3.4算术表达式 3.4.1算术运算符
C 语言中的算术运算符共有 5 个,它们是:加法运算符(+) 、减法运算符(-) 、乘法运算符(*) 、除法运 算符(/)和模(求余)运算符(%) 。 这些运算符都是双目(元)运算符,也就是说在进行运算的时候需要 2 个操作数。
3
【提示3-3】 C 语言中乘法、除法运算符的表示与数学中的表示不同,不能写成 mn, m× n, m⋅ n, m ÷ n ;也没有 乘方运算符。
相关文档
最新文档