您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第3章 运算符与表达式
•24•第3章运算符与表达式运算符和表达式是C语言的核心语法,C语言运算符丰富,不仅有优先级概念,还有结合性的概念;不仅有算术、关系和逻辑运算符,还有赋值、逗号运算符。由于C语言运算符丰富,因此表达式类型多,而且将字符、逻辑值数值化,使得C语言表达式的使用变得非常灵活。熟练掌握C语言的运算符和表达式是学好C语言的基本要求。3.1运算符与表达式概述3.1.1C运算符简介运算是对数据的加工过程,表示不同运算的符号叫做运算符,而参与运算的数据叫做操作数。不同的计算机语言有不同的运算符集。C语言中提供了丰富的运算符,它除了常规运算符如算术运算符、关系运算符、逻辑运算符外,还有如赋值运算符、逗号运算符、位处理运算符、指针运算符、访问结构体和联合体成员运算符等C语言所特有的运算符。在C语言中,除了几个控制语句外,几乎所有的操作都是通过由运算符构造的表达式来完成,因此C语言运算符的作用范围很广。1.运算符分类及属性C语言的运算符可分为如表3-1所示的15类。每个运算符除了优先级外,还有结合性等属性。一个表达式的计算顺序需要将运算符的优先级和结合性综合起来考虑。表3-1C语言运算符的优先级及结合性优先级运算符含义操作数个数结合方向举例1()[]-.圆括号下标运算符指向结构体成员结构体成员自左至右(ab)*carray[5]p-numstud.name2!~(类型)*&sizeof逻辑非按位取反自增自减负号类型转换间接访问取地址(取指针)变量或类型的长度1单目运算符自右至左!a~0(i)(i)(i)(i)x(float)n/20x*pp&xsizeof(long)sizeof(x)3*/乘法除法求余2双目运算符自左至右a*ba/b2534加法减法2双目运算符自左至右abab5左移右移2双目运算符自左至右a3a2•25•续表优先级运算符含义操作数个数结合方向举例6小于小于等于大于大于等于2双目运算符自左至右if(xy)其余运算符类似7!等于不等于2双目运算符自左至右if(xy)while(i!0)8&位与2双目运算符自左至右a&b9^位异或2双目运算符自左至右b^02410|位或2双目运算符自左至右044|c11&&逻辑与2双目运算符自左至右(ab)&&(cd)12||逻辑或2双目运算符自左至右(x1)&&(y3)13?:条件3三目运算符自右至左xab?a:b14*/&^|赋值(复合赋值)2双目运算符自右至左aabab(同aab)a*bc(同aa*(bc))a&b(同aa&b)其余复合运算符类似15,逗号2双目运算符自左至右a1,b2,c12本章将详细讨论C语言的算术运算符、赋值运算符、强制类型转换运算符、逗号运算符、关系运算符、逻辑运算符。其余的运算符将在后续章节中逐步介绍。2.关于运算符的几点说明(1)C语言的运算符按其性质分类有15类;按运算符所要求操作数的个数分类,又可以分为单目运算符、双目运算符和三目运算符。例如:“”为单目运算符,“*”、“/”为双目运算符,“?:”为三目运算符。(2)优先级别。一个表达式中可以有多个运算符,这时首先按运算符的优先级别进行运算,C语言运算符的优先级别与数学运算中的意义相同,它决定了一个表达式的运算顺序。如果一个操作数两侧有两个不同优先级别的运算符,则先执行优先级别高的运算。如49*7,在9的两侧分别为、*,根据C运算符的运算级别,则先*后。(3)结合性。如果一个操作数的两侧有两个优先级别相同的运算符,则按结合方向顺序进行处理。C语言运算符的结合性分为:①左结合性。如果一个运算符对其操作数自左至右执行规定的运算,则称该运算符是左结合的。运算符、、*、/、、&&、||等都是左结合性的运算符。例如:5*8/38两侧的运算符分别为*、/,它们的优先级相同,根据“自左至右”方向的结合原则先*后/,即8先和其左边的运算符结合(5*8),再与其右边的运算符结合(40/3)。②右结合性。如果一个运算符对其操作数自右向左执行规定的运算,则称该运算符是右结合的。运算符、!、、等都是右结合性的运算符。例如:•26•abc8b两侧都是赋值运算符“”(即优先级相同),根据“自右至左”方向的结合原则,它先与其右侧的赋值运算符结合,即a(bc8)。由于赋值运算符“”是一个双目运算符,因此b右侧赋值运算符的右边要求有一个操作数,这里是“c8”,那么是把c的值直接赋给b呢?还是先进行“c8”运算呢?由于c两侧的运算符级别相同且是“右结合性”,因此c应先与其右的赋值运算符结合,故表达式相当于a(b(c8))。关于“结合性”的概念是其他高级语言没有的,是C语言的特点之一。(4)在使用C语言的运算符时,应注意运算符对操作数类型的要求。如、、*、/的运算对象可以是整型或实型数据,而运算符(求余运算符)要求参加运算的两个操作数都必须是整型数据。(5)一个运算符两侧的操作数类型可以不同,C编译会自动进行类型转换,使二者具有同一种类型,然后进行运算。(6)C语言的运算符较多,又有其优先级和结合性,初学者要特别仔细,善于归纳。3.1.2C表达式简介用运算符将常量、变量、函数等(称为操作数)连接起来的符合C语言规定的式子称为C语言表达式。作为表达式的特例,一个单独的变量或常量也可以称为一个表达式。下面是几个表达式的例子:abc*3d/ea8yab||caabC语言中所有的运算都是用表达式表示的,清楚地了解表达式的求值顺序是正确书写表达式的关键。表达式的求值顺序取决于表达式中参与运算的运算符的优先级、结合性和语言的具体实现。例如,表达式:ab*c因“”的优先级低于“*”,所以运算顺序为先计算b*c的值,然后再与a相加。再如,表达式:n由于运算符“”(负号运算符)和“”的优先级相同,结合性均为右结合的,所以求解该表达式的顺序为:先进行n运算,然后再对运算结果求负。即相当于:(n)。3.2算术运算符和算术表达式算术运算是我们日常生活中使用最为常见的一种运算。C语言不仅提供了基本算术运算符,如加、减、乘、除和求余等,还提供了增量、减量运算符。3.2.1基本算术运算符和算术表达式1.基本算术运算符C语言中的基本算术运算符包括单目算术运算符:(负号)和双目算术运算符:•27•(加)(减)*(乘)/(除)(模除)单目运算符“”又叫做一元减运算符,其作用与数学中的负号相同,即取操作数的负值。双目算术运算符、与数学中的加、减的作用相同,而*、/则分别对应数学中的乘、除。例如,35,64,3*a,b/c等。双目运算符叫做模运算符或称为求余运算符,其作用是取被除数的模,即被除数除以除数后的余数。例如,135的结果为3,35的结果也为3,而135的结果为3。单目算术运算符“”结合方向为“自右至左”,其优先级别高于双目算术运算符,双目算术运算符的*、/、的优先级别相同,运算符、的优先级别相同,但前者的优先级别高于后者。双目算术运算符的结合方向为“自左至右”。需要说明的是:(1)运算符“”要求它的两个操作数都是整型数据。(2)其他运算符可以是任何基本数据类型。(3)若运算符“/”的两个操作数都为整数,则运算结果即商也为整数,小数部分被自然舍弃了。例如:13/5的运算结果为2,5/13的运算结果为0。参加运算的两个数只要有一个为实型,则结果是实型。2.算术表达式用算术运算符和括号将运算对象(也称操作数)连接起来的、符合C语言语法规则的式子称为C算术表达式。运算对象包括常量、变量、函数等。例如,下面是一个合法的C算术表达式:a*b/c1.5aC语言规定了运算符的优先级和结合性。在写C表达式时一定要注意运算符的优先次序和结合方向,C表达式求值时,先按优先级别高低次序执行。如果在一个运算对象两侧的运算符的优先级别相同,则按规定的“结合方向”处理。如:abc*d该表达式的运算顺序为:(1)由于b两侧的运算符的优先级别相同,则按“自左至右”结合方向进行,因此b先与减号结合,执行(ab)运算;(2)由于c两侧运算符的优先级不同,*高于,因此c先与*结合,执行(c*d)运算;(3)最后执行(ab)(c*d)运算。3.2.2增量减量运算符C语言提供了两个使变量的值增1、减1的运算符:(增量)(减量)它们都是单目运算符,其运算结果是将操作数的值加1、减1。例如:设变量i的值为5,则i后i的值将变为6,即表达式i相当于赋值表达式ii1。又如i相当于赋值表达式ii1。由于增量、减量运算符本身就隐含有赋值操作,所以它们的操作数必须是一个变量。例如:5或(ab)都是不合法的。但是,与其他单目运算符不同的是,这两个单目运算符的操作数既可以放在运算符的前面,又可以放在运算符的后边。如:i(前置增量)i(后置增量)•28•i(前置减量)i(后置减量)作为一个单独的表达式时,运算符前置和后置是没有什么区别的,但在一个还包含有其他运算的表达式中,运算符前置和后置却会产生不同的效果。在一个包含有其他运算的表达式中,增量或减量运算符的前置意味着先对其操作数进行相应的增量或减量,然后再进行其他的运算;而后置增量或后置减量运算符先对其操作数进行其他运算,然后对操作数进行相应的增量或减量运算。例3.1测试表达式中前置、后置增量运算符的运算顺序。#includestdio.hvoidmain(){inti5,j,k;ji;printf(id,jd,i,j);ki;printf(id,kd\n,i,k);}运算结果为:i6,j6,i7,k6表达式使用中应注意的问题:(1)和的结合方向是“自右至左”,即右结合性。如果有i,i的左边是负号运算符,右边是增量运算符。因负号运算符与增量运算符同优先级,而它们的结合方向为“自右至左”,故先进行“i”运算,再进行负号运算,即它相当于(i)。例如,如果i的值为3,对于printf(d,i);语句,则先取出i的值使用,输出i的值3,然后使i增值为4。另外,假若按左结合性,则上式相当于(i),而(i)是不合法的。(2)增量、减量运算符常用于循环语句中,使循环变量自动加1或减1。也用于指针变量,使指针指向下一个或上一个存储单元。这些将在后续章节中介绍。(3)在一个表达式中含有多个增量(减量)时,系统在计算表达式前,先对表达式中的增量(减量)进行扫描,并对其前置变量逐一增1(减1),然后计算表达式的值,最后再对后置变量增1(减1)操作。例3.2多个增量(减量)运算符组成的表达式的运算顺序。#includestdio.hvoidmain(){inti3,k;k(i)(i)(i);printf(id,kd,i,k);i3;k(i)(i)(i);printf(id,kd,i,k);i3;k(i)(i)(i);printf(id,kd\n,i,k);•29•}运行结果为:i6,k9i6,k18i6,k15结果分析:①首先分析表达式(i)(i)(i)的值。有人认为它相当于345,即12。事实上,用TurboC系统时它等于9。它是先把i的原值(3)取出来参加表达式的运算,因此先进行三个i相加得9;然后再使变量i进行三次增1,故i的值变为6。②分析表达式(i)(i)(i)的值。有人认为它相当于456,即15。事实上,它的值是18。原因是:i的自增1是在整个表达式计算之前就进行的,即对表达式扫描,先对i进行三次增1,i的值变为6;然后进行666的运算,故
本文标题:第3章 运算符与表达式
链接地址:https://www.777doc.com/doc-3176258 .html