6.5 操作符与抒发式
上四节详尽如是说了正则抒发式转换的方法。此栏主要讲常见操作符及抒发式,包括皮夏涅、自减、A43EI235E抒发式、单纯前提、双引号操作符以及它们形成抒发式。
操作符是具有某一排序机能的记号,是一种特定的函数同时实现。操作符有DD91操作符、双眼操作符等,前者须要三个演算第一类或繁杂程度,前者左右两端各须要三个演算第一类或繁杂程度。一般双眼演算右下繁杂程度的正则抒发式应该完全相同,假如正则抒发式不同,则手动展开隐式后展开排序。
抒发式是暗含值的演算式,在参予演算中话语权等同三个数。所以抒发式、自变量和抒发式等也是最单纯的抒发式。我们能用操作符相连抒发式形成捷伊抒发式,抒发式的正则抒发式由繁杂程度的类别的严重错误率决定。
面向对象最常用的操作符有微积分操作符、抒发式操作符、A43EI235E抒发式操作符、关系操作符、方法论操作符、双引号操作符、单纯前提操作符、位操作符等。
微积分操作符分为DD91操作符+(正)、-(负)、++(自增)、–(自减)操作符,及双眼操作符+(加)、-(减)、*(乘)、/(除)和%(取余)。在手写微积分抒发式时,*号不能略去,/的大分子和个数是繁杂抒发式时都要分别加括弧,%是只特别针对有理数的演算。要特别注意三个有理数相乘的结果是有理数,十进制部分会被弃置。
自增++和自减–操作符的繁杂程度根本无法是抒发式,用以同时实现抒发式的值加1或减1。这三个操作符能用在抒发式以后或后,其机能略有不同。如:
int i=10,j=10; i++;++i; –j;++j;等都是恰当的。但如下列抒发是严重错误的:
++(i++)、(i+10)++或 –10、(x+5)–当皮夏涅(减)操作符用在抒发式以后称作altar(减),用在抒发式后称作后加(减)。不论操作符用在前还是用在后,假如是形成抒发式句子,则二者是同构的,都同构于x=x+1或x=x-1抒发式句子。如:
int i=10,j=20; i++; //可替换++i; –j; //可替换j–;但,当altar或后加、前减或后减用于抒发式时,情况却不一样。这时不仅完成的是抒发式的皮夏涅1或者自减1的机能。整个抒发式值域的最佳时机却略有不同,altar或前减先完成抒发式抒发式后,抒发式再取抒发式的值(先加1或先减1后值域),设i=10,则抒发式(++i)的值11、(–i)的值是9,抒发式的值与演算后抒发式i的值一样;后加或后减是先把抒发式的值给抒发式,则完成抒发式的值增1或减1(先值域再加1或减1),如j=10,则抒发式(j++)或(j–)的值都是10,但j却分别变成了11或9。
掌握altar(减)和后加(关系)的关键是要抓住三个值,即抒发式值和抒发式值。不管是altar(减)或后加(减),抒发式的结果是一样的,不同的是抒发式的值是加(减)后值域还加(减)前值域。通过几个个例子辨析一下:
int n1,n2,m,k; n1=n2=2; m=++n1; k=n2++; printf(“%d,%d\n”,m,k);以上代码输出结果为:3,2。n1皮夏涅1后值为3,然后表过式(++n1)取n的值再赋给m。接下来抒发式(n2++)先取n2的值(即2),然后n2皮夏涅1,所以抒发式(n2++)赋给k,k的值为2。实际上以上代码段可近似写为:
int n,m,k;
n1=n2=2;
n1=1+1;m=n1;
k=n2;n2=n2+1;
printf(“%d,%d\n”,m,k);
很容易发现,所谓altar指的是n1在使用前先皮夏涅1,后加指的是n2使用后再皮夏涅1。
由于altar(减)和后加(减)更像是面向对象中技巧性的东西,初学者不必在上面过度花时间。但了解它们的区别对读懂他们写的程序可能是必要的。
抒发式操作符“=”是C语言特有操作符,作用是排序等号=右边的抒发式后再给左边抒发式或左值(Lvalue)抒发式,同时形成抒发式抒发式。抒发式抒发式的值取被抒发式后抒发式的值,如抒发式抒发式a=10,表示给抒发式a赋有理数10,同时抒发式“a=10″也值域10,因此能将该抒发式的值又赋给另三个抒发式以同时实现连续抒发式,如:
b=(a=10);由于抒发式操作符按照从右至左的顺序结合,因此以上抒发式能写成:
b=a=10;以上抒发式并不是把10分别赋给a和b三个抒发式,而是把10先赋给a后,再把抒发式(a=10)的值赋给b。
A43EI235E抒发式操作符指的是操作符与抒发式号组合形成的操作符,基本形式为: op=,op表示操作符,能是+、-、*、/、%及位操作符等,=号表示抒发式,A43EI235E抒发式演算相连抒发式与抒发式形成A43EI235E抒发式抒发式。要特别注意A43EI235E抒发式操作符左边必须是抒发式或合法的左值(Lvalue),右边能是任何抒发式。作用是把左边抒发式的值与右边抒发式的值作op演算后,再赋给左边抒发式,A43EI235E抒发式抒发式:
抒发式 op= 抒发式
与抒发式抒发式
抒发式 = 抒发式 op 抒发式
抒发式号左右两端的“抒发式”是同三个抒发式。如前面学到的“sum=sum+数据项i”“f=f*i”能分别写成:
sum += 数据项i; f=f*i;而x=x*(y-3)能写成 x *= y-3。
A43EI235E抒发式演算也能作为三个抒发式用在其它抒发式中,这时A43EI235E抒发式抒发式的值与左边被抒发式以后的抒发式相等。如下列代码:
int a,b; a=10;b=20; a+=b*=a-5; printf(“a=%d,b=%d\n”,a,b);代码执行结果是:a=110,b=100。A43EI235E抒发式也是按从右至左的顺序结合的,所以先执行“b*=a-5”,结果b的值和抒发式的值都为100,再做a+=100,所以a的值为110。假如代码中a-5变为a=5,则结果又是什么呢?请您思考。
关系操作符能完成三个繁杂程度的比较,有大于>、小于<、大于或等于>=、小于或等于<=和等于==、不等于!=六种。关系操作符形成关系抒发式,其值根本无法有0和1两种结果,分别表示假和真。关系操作符按从左至右相结合,>、<、>=、<=严重错误率完全相同,且比==和!=高。关系操作符的严重错误率低于微积分操作符,但高于抒发式操作符。如下列三个抒发式是合法的,如:
(1)4<x<10 和 (2)x<4!=0设x为3时,抒发式(1)从左至右排序,4<x的排序结果为0(假),再排序0<10,结果为1(真)。所以抒发式(1)不能表示x在区间4和10之间。抒发式(2)先排序x<4,结果1,再排序1!=0,结果为1(真)。
方法论操作符能相连各类抒发式构造出较繁杂的前提抒发式。主要有方法论与(&&)、方法论或(||)与方法论非(!)三种,前面两种是双眼演算,后一种是DD91演算。方法论与(&&)的严重错误率大于方法论或(||),这种两操作符的严重错误率都低于关系操作符,但比抒发式操作符高。方法论非(!)的严重错误率比微积分演算的严重错误率高,如:
判断x在区间[5,20]以内能用 x>=5 && x<=20表示,判断ch是大写字母能用 ch>=A && ch<=Z表示,要判断ch是数字字符能有ch>=0 && ch<=9。方法论与构成抒发式的值只有操作符两端结果都为真(非0)时,结果才为1(真),只要有三个抒发式为假,结果一定为假。因此抒发式 4 && -1 的结果为1,但4 && 0的结果为0。
判断x的值在区间[5,20]之外能用x<5 || x>20表示。
如当x分别为1时,有x<5为真,所以抒发式的值为1(真),当x为10时,操作符两端的抒发式都为假,结果为0(假)。
方法论或演算只要两端的抒发式有三个为真(非零)时,结果就为真,只有三个同时为假时,结果才为假。 所以有5 || 0为真,0 || 0为假。
方法论非(!)是把真变假,假变真的操作符。如表示x在区间[5,20]之外的抒发式,除了可用x<5||x>20之外。还可以用!(x>=5 && x<=20)表示,意味着x不在[5,20]区间内,事实上两种表示法是同构的。!0的结果为1,!1的结果为0。
抒发式:
a>20 || 3 + 10 && 2含有微积分操作符、方法论操作符和关系运算符,排序严重错误率是什么呢?首先排序微积分演算3+10,结果为13。然后排序a>20结果为0或1,抒发式化简为
(0或1) || 13 && 2因为&&高于||,所以排序13&&2,结果为1。再与前面的值展开||运算,结果为1。所以抒发式不论a为多少,结果都是1。
方法论演算最容易搞错的是其“短路原理”。即A||B中,只要排序A为1,B不再排序。A && B中要排序A为零,B也不用再排序。如代码段:
int a=3,b=5; int c,d; c= (a+=3) || (b+=5); d= (b-=5) && (a=10); printf(“a=%d,b=%d,c=%d,d=%d\n”,a,b,c,d);在给c抒发式时,由于A43EI235E抒发式抒发式a+=3的值为6且抒发式a也变成了6,根据“短路原理”,不再排序b+=5,所以b的值不变。在给d抒发式时,A43EI235E抒发式句子b-=5的值为0(假),b的值也为零,所以不再排序a=10,所以a的值保持不变。所以最后显示结果为:a=6,b=0,c=1,d=0。特别注意的是抒发式操作符的严重错误率比方法论操作符低,所以要先加上括弧。
例2:请写出判断x与y不能同时为零的抒发式。
(1)最单纯的方法是先写出同时为零的抒发式 x==0 && y==0,然后加上!操作符,即!(x==0 && y==0);
(2)不同时为零,就是至少有三个不为零,能用方法论或演算,即:x!=0 || y!=0;
(3)由于抒发式x!=0只有当x是非0时为真,是0为假,因此x!=0同构于x,所以(2)能简写为:x || y。
单纯前提操作符(?:)是根据三个前提抒发式的值来确定抒发式的值域。形成的抒发式称作简前提抒发式,基本格式如下:
e1 ? e2 : e3
e1称作前提抒发式,先排序抒发式e1的值,假如e1的结果为1(真),则选择抒发式e2的值,否则选择抒发式e3的值。单纯前提抒发式常见来简化某些if_else句子。如:
if(x>=60) y=1; else y=0;能用单纯前提抒发式写成:
y = (x>=60) ? 1: 0;原来用几行写完的代码,现在一行就能写完,代码更加简洁易读。
再来看三个判断空间是否用完的程序,如果n表示现阶段已经使用空间,MAXSIZE表示最大申请空间。假如空间用完抒发式返回1(真),否则返回0(假)。用if_else句子是这样写的:
if(n==MAXSIZE) return 1; else return 0;用单纯前提抒发式可简写为:
return n==MAXSIZE ? 1 :0;最后来看一下求三个抒发式最大值的单纯前提抒发式如何写?用三个单纯前提抒发式就可省掉三个if_else句子的手写。
max=( a > b) ? a : b; max= (c > max)? c : max;双引号操作符(,)是用以相连一系列抒发式,双引号操作符相连的抒发式系列称作双引号抒发式,其值域为最后三个抒发式的值。用法如下:
抒发式1,抒发式2,….,抒发式n如下列例子:
int a, b, c; (a=2), (b=3), (c=a+b);由于双引号操作符的严重错误率最低,比抒发式操作符还要低。所以,上面第二行括弧能略去如下:
a=2, b=3, c=a+b;特别注意,不要错把2,b=3,c=a+b理解为双引号抒发式。该抒发式的第三个抒发式是a=2。我们能用双引号抒发式把多条抒发式句子或A43EI235E句子变成一前提句子,如上面的抒发式对应的是下列三条句子。
a=2; b=3; c=a+b;双引号抒发式能用在for句子中的e1和e3抒发式中,如求累加和的程序原来为:
sum=0; for(i=1;i<=n;i++) sum=sum+i;能把sum=0合到for的抒发式e1中,能把sum=sum+i合到抒发式e3中,结果for句子变成了这样:
for(sum=0,i=1;i<=n;sum=sum+i,i++) ;
用一行for句子完成原来的机能,这时循环体只是三个分号而已。
最后讲一下sizeof操作符。sizeof是三个操作符,不是三个抒发式,能用以获得自变量、抒发式、抒发式和正则抒发式等占用内存空间的大小。
要查看正则抒发式占用空间的大小,直接在sizeof后面跟正则抒发式即可,如:
sizeof(int),sizeof(long long)可分别获得整型和长长整型应该占空间的大小。
假如想查看自变量、抒发式或抒发式应占用存储空间的大小,能如下使用sizeof操作符,如:
int a; double b; printf(“%d,%d,%d,%d\n”,sizeof(a),sizeof(b),sizeof(4),sizeof(a+2.0));程序运行结果为:
4,8,4,8说明了抒发式a与自变量4都是int型的,抒发式b与抒发式a+2.0都是双精度型。
此栏简要如是说了微积分操作符、关系操作符和方法论操作符以及它们形成的抒发式,深入如是说了皮夏涅、自减操作符、A43EI235E抒发式操作符、单纯条件操作符等及其相应抒发式的使用。此栏就讲到这里,下四节再见!