表达式与操作符_第1页
表达式与操作符_第2页
表达式与操作符_第3页
表达式与操作符_第4页
表达式与操作符_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章表达式与操作符表达式和语句的概念及其关系;各种操作符语句的使用;操作符之间的优先级和结合性;了解词法分析中的分析法;使用小括号改变操作符的执行顺序。5.1表达式和语句在C语言中,语句是程序功能的基本执行单位,多个语句结合在一起可以完成一些特定的功能;而一个语句又由若干个表达式组成;此外,语句和表达式可以通过一定的手段来相互转换。本节将讨论表达式和语句的概念和使用。5.1.1表达式表达式是C语句的主体。在C语言中,表达式由操作符和操作数组成。操作符可以是+、-、*、/或%一类的运算操作符,也可以是>、<或==之类的关系操作符,还可以是其他一些操作符。操作数是操作符的操作对象,可以是常量或变量。最简单的表达式可以只含有一个操作数,例如:73.1415926“hello,world”variable5.1.1表达式根据表达式含有的操作符的个数,可以把表达式分为简单表达式和复杂表达式:简单表达式是只含有一个操作符的表达式;复杂表达式含有两个或两个以上操作符。下面分析两种表达式的含义和它们的执行过程。1.简单表达式简单表达式由于只含有一个操作符,运行方式比较简单。下面列举了几个简单表达式,其中接触到的操作符在后面几节将详细讲解。c=2 /*表达式1*/4+25 /*表达式2*/ptr==NULL /*表达式3*/key>max /*表达式4*/fun(b) /*表达式5*/5.1.1表达式2.复杂表达式在复杂表达式中,每一个操作符和它的操作数组成的表达式为复杂表达式的子表达式。例如:b=d+e;下列5个表达式都是复杂表达式,它们依次是上面的5个简单表达式的复杂化版本。c=b+2 /*表达式1*/4+25*3 /*表达式2*/*ptr==length /*表达式3*/key+incre>max /*表达式4*/fun(7+5-3) /*表达式5*/5.1.2语句语句是计算机运行C程序的基本执行单元,一个程序是由一系列的语句组成。在C语言中,一条完整的语句由表达式和分号的。例如:/*表达式;*/var=2;其中的表达式部分可以是最简单的表达式,也可以是很冗长的复杂表达式,还可以为空。最简单的语句就是一条空语句,即只有一个分号,如下所示;5.1.2语句这个语句虽然什么都没有做,但是有时候在逻辑上却需要这样的空语句。例如,要求在一个数组里得到某个值的下标,程序如下所示:for(inti=0;i<max&&array[i]!=target;++i); /*功能已完整,无需执行体*/上面是一个完整的for语句结构。在功能上,只需要执行循环判断部分(i<max&&array[i]!=target;)就可以完成查找功能;但是,在程序结构上,for结构还需要一个循环体,因此这里需要一条空语句。关于for语句,在第5章将详细讨论。5.1.3复合语句复合语句,也可以称为程序块,是包含在花括号({})内的多个语句的集合。标准形式如下所示:{语句1;语句2;语句3;……}5.1.3复合语句C语言的执行都是逐条语句依次执行的。但是为了实现一些复杂的功能,很多程序常常需要把几条语句作为一个功能单元来执行,这时就需要使用复合语句把多条语句绑定为一个整体。1.组成特殊语句结构复合语句主要用在C语言的特殊语句中,比如if语句、for语句和while语句等,构成这些语句的执行体,以实现一些复杂的功能。例如,要执行一个功能:当a大于b时,互换变量a和变量b的值;当a不大于b时,什么都不做。程序如下所示:01 /*当a大于b时,互换变量a和变量b的值*/02 if(a>b){ /*if语句*/03 c=a;04 a=b;05 b=c;06 }5.1.3复合语句如果不使用花括号把三条操作语句联合为复合语句,将无法实现正常的功能,例如:01 if(a>b)02 c=a;03 a=b;04 b=c;对齐代码后,等效于:01 if(a>b)02 c=a;03 a=b;04 b=c;5.1.3复合语句2.提高程序可读性除了用在特殊语句内,复合还可以将一些完成单一功能的语句放在一个花括号中,以提高程序可读性。3.嵌套使用复合语句还可以嵌套使用。5.1.3C操作符操作符是C语言的重要组成,也是本章要讨论的重点。C语言提供了丰富的操作符,以完成各种各样的功能。C语言共有45个操作符,简单地分类展示如下:后缀操作符(4个):()[].->算术操作符(7个):+-*/%++--符号操作符(2个):+-逻辑操作符(3个):!&&||5.1.3C操作符关系操作符(6个):>>=<<===!=位操作符(6个):~>><<&^|条件操作符(1个):?:赋值操作符(11个):=*=/=%=+=-=<<=>>=&=^=|=逗号操作符(1个):,转型操作符(1个):(数据类型名)即(int)、(char)等地址操作符(2个):*&求字节操作符(1个):sizeof()5.1.3C操作符下面来讨论如何区分既可作为运算操作符,也可以作为地址操作符的*。01 pro=a*b;02 b=*ptr;03 pro=a**ptr; /*两个*中间以及两边的空格可以为随意多个,也可以没有*/5.2赋值操作符与赋值表达式赋值操作符是C语言中最常用的操作符之一,其功能是为变量赋值。由赋值操作符所组成的表达式称为赋值表达式。本节将先讨论赋值操作符和赋值表达式的使用,在介绍左值和右值的概念,最后讨论赋值表达式中常见的类型转换的问题。5.2.1赋值操作符赋值操作符是一个二元操作符,其组成的赋值表达式的标准形式由变量、赋值操作符和一个表达式组成,如下所示:变量=表达式;赋值表达式的作用,就是把等号右边的表达式的值赋值给等号左边的变量。其中,赋值操作符左边的变量也称为左值,右边的表达式称为右值。赋值表达式的值即为语句执行后左值的值。5.2.2赋值操作符的结合性

当多个赋值操作符存在于同一条语句中时,按照C标准的规定,将会按照从右到左的结合方式先执行最右边的赋值操作符,再依次向左执行其余赋值操作符。例如:a=b=c=表达式;该语句会先执行最右边的赋值操作符,再执行中间的,最后执行左边的,即等效于:a=(b=(c=表达式)); /*括号操作符的优先级是最高的*/5.2.3左值和右值在C语言中,左值和右值是十分重要的概念。并不是所有的值都是可以改变的,可以改变的值被称为左值。之所以要称为左值,还因为只有可以改变的值才能放在赋值操作符的左边,即只有左值可以放在赋值操作符的左边,也可以说放在赋值操作符左边的都是左值。左值可以是变量,如下所示:intyear=2008;int型变量year被赋值为2008。左值也可以是部分表达式,如下:int*month;*month=2;5.2.4赋值表达式中的类型转换在赋值表达式中,当把一种类型的数据赋值给不同类型的变量时,编译器会隐式地把该数据进行类型转换,转换为该变量的类型后才赋值。例如:intsmall=2008;longlongintlarge;large=small;5.2.5类型转换操作符类型转换操作符是操作符中十分独特的一个,由一个小括号及包含在小括号里的一个类型名称组成,如下所示:(int)(longlongint)(float)类型转换操作符也是一个一元操作符,只带一个操作数,使用时放在操作数的前面。它的作用是把操作数的值的数据类型改变为操作符中的数据类型。如下所示为类型转换操作符的标准形式:(数据类型名)(表达式)5.2.5类型转换操作符下面是几个使用类型转换符的实例:inti=(int)3.11;floatf=(float)7;shortintv=(shortint)28;其中,double型常量3.11会转换为整型(会丢失数据)后赋值给int型变量i,int型变量7会转换为float型(不会丢失数据)后赋值给float型变量f,int型数据28将转换为shortint型(不会丢失数据)后赋值给shortint型变量v。当表达式不仅仅是一个变量或一个常量时,需要把表达式放在小括号内。例如:m=(int)(3.7+2.5)这时,程序会对3.7和2.5的和类型转换为int型。如果没有括号,只是:m=(int)3.7+2.55.3运算操作符与运算表达式数值计算离不开运算操作符,都要依靠运算操作符将各种数值连接在一起来完成特定的数值计算。由运算操作符组成的表达式为运算表达式。本节将讨论各种基本运算操作符和运算表达式的使用,同时还讨论与它们密切相关的符号操作符,以及运算表达式中的优先级、结合性和类型转换的问题。5.3.1运算操作符运算操作符共有五个,分别是加法操作符(+)、减法操作符(-)、乘法操作符(*)、除法操作符(/)和求余操作符(%)。它们均为二元操作符,即操作符前后都需要有一个操作数。5.3.1运算操作符1.加法操作符加法操作符的功能即进行加法运算。例如:var=3+4+5+6+7;赋值操作符右侧为一个复杂的加法表达式,程序将先计算3和4的和,再计算该和与5的和,再计算该和与6的和,再计算该和与7的和,最后将最终的和赋值给var。当然,操作数也可以是变量。例如:printf(“sum=%d”,a+b); /*变量a和b为加法操作符的两个操作数*/5.3.1运算操作符2.减法操作符减法操作符的功能即,进行减法运算。例如:diff=512–128;赋值操作符右侧即为减法表达式,将计算512和128的差作为该表达式的值,最后赋值给变量diff。5.3.1运算操作符3.乘法操作符乘法操作符的功能是将它的操作数进行乘法计算,得到的值作为乘法表达式的值。例如:area=length*width;赋值操作符右侧即为一个乘法表达式,将计算变量length和变量width的乘积作为该子表达式的值,最后将该值赋值给area。5.3.1运算操作符4.除法操作符除法操作符的功能是将它的操作数进行除法运算,将得到的值作为除法表达式的值。例如:rate=distance/time;赋值操作符右侧为一个除法表达式,其功能是计算变量distance除以变量time的商,最后将该值赋给变量rate。5.3.1运算操作符5.求余操作符求余操作符的功能是求其左侧的操作数除以右侧操作数的余数。例如:digit=number%10;赋值操作符右侧为一个求余表达式,其作用为计算变量number除以10的余数,即变量number的个位数,最后将该值赋值给变量digit。5.3.2符号操作符减法操作符(-)和加法操作符(+)不仅可以作为运算操作符,还可以作为符号操作符。1.负号操作符负号操作符是一元操作符,其作用是改变操作数的符号。它的操作数跟在操作符后面,可以是整型、浮点型或字符型的常量或变量。例如:-25-74.0-‘c’-a5.3.2符号操作符2.正号操作符正号操作符与负号操作符的使用方法类似,也是一元操作符,其操作数也放在操作符后面,也可以是整型、浮点型或字符型的常量或变量。但是,正号操作符的用途没有负号操作符广,因为和数学意义上的正号意义,在一个数前面加上正号不会改变该数的值。例如:+(-25)+25+a5.3.3优先级与结合性操作符的优先级是指操作符执行的先后顺序。当多个操作符共同存在于一个复杂表达式中时,需要按照一定的先后顺序执行;优先级高的操作符会比优先级低的操作符先被执行。例如:result=15+7*12–7/4;5.3.3优先级与结合性下表总结了所有已接触到的操作符的优先级和结合性。其中优先级从上到下依次降低。5.3.4数值运算中的类型转换

在运算表达式中,当不同类型的数值之间进行运算时,编译器也会像在赋值表达式中那样进行隐式的类型转换。例如:area=4*7.5;其中,4为int型,7.5为double型。int型的4将先被转换为double型再与double型的7.5相乘。5.3.4数值运算中的类型转换

数值运算中的类型转换遵从以下规则:char型和short型数据,不管是unsigned还是signed,在计算中都要先无条件转换为int型,即使是两个char型或short型数值相加。float型计算前会无条件转换为double型数值,以增加精度。其余类型的数值计算时,都要转换为数据类型级别较高的后再计算。5.3.4数值运算中的类型转换

数据类型级别是以能存储的数值范围来定义的,能储存的数值范围越大,数据类型级别越高。如下图所示:5.3.5复合的赋值操作符赋值操作符与上面介绍的五种基本运算操作符结合,可以组成复合的赋值操作符:+=,-=,*=,/=和%=。他们使用形式与赋值操作符相似,都是二元操作符,而且左侧也只能为左值,右侧为右值;但是功能上比赋值操作符复杂。1.+=该操作符由赋值操作符与加法操作符结合而成的,其使用形式为:左值+=右值;其作用为,将左值与右值相加的和赋给左值,等效于:左值=左值+右值;5.3.5复合的赋值操作符2.-=该操作符由赋值操作符与减法操作符结合而成的,其使用形式为:左值-=右值;其作用为,将左值与右值相减的差赋给左值,等效于:左值=左值-右值;3.*=该操作符由赋值操作符与乘法操作符结合而成的,其使用形式为:左值*=右值;其作用为,将左值与右值相乘的积赋给左值,等效于:左值=左值*右值5.3.5复合的赋值操作符4./=该操作符由赋值操作符与除法操作符结合而成的,其使用形式为:左值/=右值;其作用为,将左值与右值相除的商赋给左值,等效于:左值=左值/右值;5.%=该操作符由赋值操作符与求余操作符结合而成的,其使用形式为:左值%=右值;其作用为,将左值对右值求余的结果赋给左值,等效于:左值=左值%右值;5.4自增、自减操作符为了简化程序书写,C语言中还定义了两种操作符:自增操作符(++)和自减操作符(--)。这两种操作符都是一元操作符,只带一个操作数;同时,这两个操作符可以放在它们的操作数的左边,也可以放在右边,两者的功能是不同的。本节将介绍自增操作符和自减操作符的语法和使用时需要注意的问题,同时还将讨论贪婪法的内容。5.4.1自增操作符顾名思义,自增操作符就是使自己的值增加的操作符。准确地说,自增操作符的作用是将其唯一的操作数赋值为其自身值加1后的值。由于该操作数会被赋值,因此必须是左值,即要求其值是可以改变的。自增表达式的标准形式如下:左值++5.4.2自减操作符自减操作符与自增操作符使用方法完全一样,也为一元操作符。它可以放在其唯一的操作数(称为前自减操作符)的前面,也可以放在操作数的后面(称为后自减操作符)。自减操作符的作用是将其操作数减1后再赋值给本身。自减操作符也有前自减操作符和后自减操作符:前自减操作符是在执行所在语句前自减1,而后自减是在执行语句后自减1。5.4.3优先级与结合性自增操作符和自减操作符的优先级与符号操作符相同。在上面的案例中,已经接触到它们的优先级的使用,例如范例5-13中的第8行:y=--x+1;由于,自减操作符的级别最高,所以先执行前自减的操作。但是需要注意的是,在第12行中:y=1+x--;5.4.4词法分析:贪婪法词法分析是指编译器把C程序中的字符处理为一个个C语言中的符号的过程。C语言中的操作符有单字符的(例如=、+、-),也有两个字符的(例如++、--),还有更多字符的(例如类型转换操作符)。由于,C语言允许两个操作符之间可以没有空格(例如v=+d,其中=+为两个操作符),因此某些字符在一起可以组合成多种不同情况的操作符,例如:++bbb;5.4.4词法分析:贪婪法理论上,++除了可以视为前自增操作符,也可以视为两个正号操作符,等效于:+(+bbb);例如:+++++++b; /*7个+*/按照贪婪法,分析的结果等效于:+++++++b;再进行语法分析,自增操作符与加法操作符结合性为从右到左,分析结果等效于:++(++(++(+b)));5.4.5自增、自减操作符的副作用所谓自增操作符和自减操作符的副作用就是,它们在执行它们所在语句之前或之后对操作数的自增和自减操作。由于这些操作与语句是在不同阶段执行的,在一些复杂的情况下,程序员常常因此会犯错误。甚至于在不同的编译器中,这些语句的结果也是不尽相同的。在编程过程中,应当尽量消除这些副作用可能导致错误的隐患。5.5关系操作符与关系表达式在前面的范例中,已经接触到很多关系操作符的例子。关系操作符在C语言中主要用于进行数值比较。由关系操作符组成的关系表达式通常用在程序中的控制选择语句中。本节将讨论关系操作符和关系表达式的使用,以及关系操作符的优先级和结合性。5.5.1使用关系操作符关系操作符包括小于操作符(<)、大于操作符(>)、小于等于操作符(<=)、大于等于操作符(>=)、等于操作符(==)和不等于操作符(!=)6种。使用关系操作符的标准方式如下:1.小于操作符(<)表达式1<表达式2该表达式为小于表达式,当表达式1的值小于表达式2的值时,为真;否则,为假。2.小于等于操作符(<=)表达式1<=表达式2该表达式为小于等于表达式,当表达式1的值小于等于表达式2的值时,为真;否则,为假。5.5.1使用关系操作符3.大于操作符(>)表达式1>表达式2该表达式为大于表达式,当表达式1的值大于表达式2的值时,为真;否则,为假。4.大于等于操作符(>=)表达式1>=表达式2该表达式为大于表达式,当表达式1的值大于等于表达式2的值时,为真;否则,为假。5.等于操作符(==)表达式1==表达式2该表达式为等于表达式,当表达式1的值等于表达式2的值时,为真;否则,为假。5.5.1使用关系操作符6.不等于操作符(!=)表达式1!=表达式2该表达式为不等于表达式,当表达式1的值不等于表达式2的值时,为真;否则,为假。关系表达式的计算是一个比较的过程,如果被比较的两个值类型不同,必须先进行类型转换。例如:4>4.312==‘f’第一个表达式中,int型4要转换为double型后再比较;第二个表达式中,char型’f’要转换为int型后再进行比较。范例5-17演示了各种关系操作符的使用。5.5.2关系表达式的值虽然C99定义了_BOOL,但现在大部分编译器并不支持这一类型,而即使_BOOL型也不是关系表达式的值类型。关系表达式值在C语言中实际上作为int型处理。同时,已经知道非0的数值的布尔值为真,而为0的数值的布尔值为假;那么反来过,布尔值如何转化为int型值?关系表达式的布尔值如何转换为int型值?布尔值转换为int型值,一般遵从以下规则:假

0真

1布尔值为真的关系表达式的int型值为1,布尔值为假的关系表达式的int型值为0。范例5-18验证了关系表达式的值和它的数据类型。5.5.3优先级与结合性不同关系操作符的优先级不同,其优先级如下:较高优先级:<、<=、>、>=(这4个优先级相同);较低优先级:==、!=(这2个优先级相同)。相同优先级的关系操作符的结合性为从左到右。关系运算符的优先级比赋值运算符高,比运算操作符低,例如:m=1+2*3==4;5.6逻辑操作符与逻辑表达式逻辑操作符包括逻辑与操作符(&&)、逻辑或操作符(||)和逻辑非操作符(!)三种,其功能是进行各种逻辑运算。含有逻辑操作符的表达式即为逻辑表达式。C语言中一些复杂功能的实现离不开逻辑表达式的使用。本节将讨论逻辑操作符和逻辑表达式的使用,同时还讨论了如何化简逻辑表达式。5.6.1使用逻辑操作符三种逻辑操作符的使用形式如下:1.逻辑与操作符逻辑与操作符是个二元操作符,其标准调用方式如下:表达式1&&表达式2该表达式为逻辑与表达式,其中表达式1和表达式2可以为任意表达式,其功能为将两个表达式的布尔值做逻辑与运算。逻辑与运算规则如下:真&&真=真真&&假=假假&&真=假假&&假=假5.6.1使用逻辑操作符2.逻辑或操作符逻辑或操作符也是二元操作符,其标准调用方式如下:表达式1||表达式2该表达式为逻辑或表达式,其中表达式1和表达式2也可以为任意表达式,其功能为将两个表达式的布尔值做逻辑或运算。逻辑或运算规则如下:真||真=真真||假=真假||真=真假||假=假5.6.1使用逻辑操作符3.逻辑非操作符逻辑非操作符为一元操作符,只带一个操作数,使用时操作符位于操作数前,调用形式如下:!表达式1该表达式为逻辑非表达式,其中表达式1和表达式2也可以为任意表达式,其功能为将两个表达式的布尔值做逻辑非运算。逻辑非运算规则如下:!真=假!假=真5.6.2逻辑表达式的值与关系表达式相同,虽然逻辑表达式在本书介绍中认为是布尔值,但C编译器中将其处理为int型。如果逻辑表达式的布尔值为真,则其int型值为1;如果其布尔值为假,则其int型值为0。5.6.3优先级和结合性3个逻辑操作符的优先级从高到低为:逻辑非操作符、逻辑与操作符和逻辑或操作符。结合性为从左到右。同时,逻辑非操作符的优先级与符号操作符一致,比运算操作符高,更比关系操作符高;逻辑与操作符和逻辑或操作符的优先级低于关系操作符,但高于赋值操作符。5.6.4化简逻辑表达式3个逻辑操作符组合使用时,可以得到多个功能一致但形式不同的逻辑表达式。使用简单的逻辑表达式来代替复杂的表达式是提高程序逻辑性的一个重要方法。下面是两组功能一样的逻辑表达式:第一组表达式如下:!(a||b)!a&&!b第二组表达式如下:!(a&&b)!a||!b使用以上功能相同的两组逻辑表达式可以对一些复杂的、逻辑不清的表达式进行简化。5.7逗号操作符与逗号表达式逗号操作符是C语言中很重要的辅助型操作符。逗号操作符所在的表达式称为逗号表达式。在逗号表达式中,逗号操作符将若干个表达式连接在一起形成一个语句。本节将讨论逗号操作符和逗号表达式的使用。5.7.1使用逗号操作符逗号操作符是一个二元操作符,其标准使用形式如下:表达式1,表达式2该逗号表达式会以从左到右的顺序先计算表达式1,再计算表达式2。逗号表达式的优先级是所有操作符中最低的,因此可以将任意表达式直接作为逗号表达式的子表达式,且不会改变表达式的执行顺序和执行逻辑。5.7.2逗号表达式的值与其余表达式一样,逗号表达式也有一个值,其值等于表达式中最后一个子表达式的值。即:表达式1,表达式2,表达式3……

表达式n;上述表达式的值等于表达式n的值。范例5-22演示了逗号表达式的值及其使用方法。5.8操作符优先级和结合性优先级和结合性是操作符使用中十分重要的知识,在前面的讨论中已经多次涉及。本节将总结C语言中所有操作符的优先级和结合性,包括一些本章未介绍的操作符。此外,本节还介绍了两种更好地使用表达式的方法。5.8.1优先级和结合性操作符的优先级代表了它被执行的优先度。当一个复杂表达式里含有多个操作符时,一般情况下,首先会根据操作符的优先级来决定操作符的执行顺序;但操作符的优先级相同时,应该根据操作符的结合性来判断执行顺序。5.8.1优先级和结合性右表是所有操作符优先级和结合性的总结。5.8.1优先级和结合性1.前置操作符前置操作符都是一元操作符,其优先级为2,为第二高。很容易理解将它们得结合性规定为从右到左的原因,例如:+-

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论