当前位置:文档之家› C++运算符的优先级与结合性

C++运算符的优先级与结合性

C++运算符的优先级与结合性
C++运算符的优先级与结合性

c/c++运算符的优先级和结合性

内容导读:遍历了15个级别之后,让我们再来总结一下。其中我们可以看出这样两个规律:规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符; 规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算...

遍历了15个级别之后,让我们再来总结一下。其中我们可以看出这样两个规律:

规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符;

规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算符,位移运算符,关系运算符,位运算符,逻辑运算符,赋值运算符。

此外还有两特别的地方需要注意:

一、同为关系运算符,但==和!=的级别低于其它四个;

二、第2组与第13组的操作符是右结合的,其它的都为左结合;

通过分类我们大大减少了需要记忆的内容,遇到使用操作符的时候,我们只需想想它们是什么类型的运算符就可以确定它们之间的相对优先级,从而避免一些不必要的错误。

====================================================================== ===================

提起运算符的优先级,很多了解c++的过来人都会想:这有什么难的?不就是谁的优先级高就算谁么。确实如此,运算符的优先级不是一个大问题,但对于一个初学者来说,却经常容易在上面迷糊与犯错。而对于一个了解c++的人来说,我相信也会偶尔在上面摔倒,不信就继续往下读。

“优先级高的先运算”带来的困惑

c++中运算符的优先级有一张表,表里把运算符进行了分类,这张表是不需要死记硬背的,只要有个大致的轮廓就ok了。例如应该记住最低优先级是逗号运算符,其次是赋值运算符,再其次是三目运算符。而关系运算符的优先级高于逻辑运算符(不包括逻辑非运算),算术运算符的优先级高于关系运算符,象++和﹣﹣的优先级比前面几个都高,但最高的要属()了。知道这些后,你的脑海里一定有一条准则了:优先级高的先运算。那么下面看一个例子:

intx=1,y=0;

!x&&x+y&&++y;

上面的语句中出现了!、&&、+、++这四个运算符,那么问题来了,到底先算谁呢?

有一个姓蔡的同学站起来说,++运算符在这里面优先级最高,理所应当最先算++,既先计算++y,再算!x,再算x+y,最后把它们&&起来。按照蔡同学的思路,第二步的结果是0&&x+y&&1,由于&&是严格运算,有一个为0结果既为0,所以不需要计算x+y了,整个语句的结果是:假。按照上面蔡同学的说法,执行完后y的值应该是1了,这对不对呢?

一位姓高的同学站起来反驳道,我觉得应该先计算!x,如果值为假,则不需要计算下去,最后结果为假。如果值为真,再计算x+y,同理如果其值为真,再去计算++y,否则最后结果也为假。

蔡同学不服起来说,高同学你觉得++和!谁的优先级高呢?高同学答道,那当然是++高。蔡同学接着问,那为什么还要先计算!呢?高同学答不出来了。

是呀,为什么要先算!呢?

加括号确定优先级的方法

高同学说的是正确的,为什么呢?下面我给大家解释一下。当多个优先级不同的运算符在一起时,为了不混淆,可以先加上括号,这样就分出层次了,相同层次的考虑结合性问题,当确定下来先算那块时,再往这块里面深入。例如上面的例子,我们可以这样加上括号:从左向右看,由于!比&&优先级高,所以有(!x),又由于&&比+优先级低,所以有(x+y),而++优先级高于&&,所以(++y)。这样整个式子就变成了:(!x)&&(x+y)&&(++y),最外层的是两个&&运算,由于&&的结合性是从左至右,所以上式可看成:a&&b&&c,先计算a,再计算b,最后算c。由于x=1,则!x就为假,后面的就不需要再算了,整个语句的值为假。执行完后,y的值没变,还是0。

所以碰到不清楚先算谁后算谁时,先加个括号看看,就明白了先后次序。下面做一个加括号的练习:给语句c=a>b?a:b;加括号。此语句有三个运算符:=、>、?:,应该怎样加括号呢?

第一种方案:c=((a>b)?a:b);

第二种方案:c=(a>(b?a:b));

第三种方案:(c=a)>(b?a:b);

应该是那一种呢?按照运算符优先级的高低顺序,>优先级高于=,所以不可能把(c=a)括起来。而>优先级高于?:运算符。所以也不可能把(b?a:b)括起来。因此,第一种答案正确。

下面再看一个类似的例子:

inti=8,j=4,k;

k=i

猛然一看,有些人上来可能就要计算++i和++j了。这里不妨先加括号看看。从左至右看,<的优先级高于=而且又高于?:,所以有k=(i

==============================

每个操作符拥有某一级别的优先级,同时也拥有左结合性或右结合性。优先级决定一个不含括号的表达式中操作数之间的“紧密”程度。例如,在表达式ab+c中,乘法运算的优先级高于加法运算符的优先级,所以先执行乘法ab,而不是加法b+c。

但是,许多操作符的优先级都是相同的。这时,操作符的结合性就开始发挥作用了。在表达式中如果有几个优先级相同的操作符,结合性就起仲裁的作用,由它决定哪个操作符先执行。像下面这个表达式:

inta,b=1,c=2;

a=b=c;

我们发现,这个表达式只有赋值符,这样优秀级就无法帮助我们决定哪个操作先执行,是先执行b=c呢?还是先执行a=b。如果按前者,a=结果为2,如果按后者,a的结果为1。

所以的赋值符(包括复合赋值)都具有右结合性,就是说在表达式中最右边的操作最先执行,然后从右到左依次执行。这样,c先赋值给b,然后b在赋值给a,最终a的值是2.类似地,具有左结合性的操作符(如位操作符“&”和“”)则是从左至右依次执行。

结合性只用于表达式中出现两个以上相同优先级的操作符的情况,用于消除歧义。事实上你会注意到所有优先级相同的操作符,他们的结合性也相同。这是必须如此的,否则结合性依然无法消除歧义,如果在计算表达式的值时需要考虑结合性,那么最好把这个表达式一分为二或者使用括号。

==============================

裘宗燕:c/c++语言中的表达式求值

经常可以在一些讨论组里看到下面的提问:“谁知道下面c语句给n赋什么值?”

m=1;n=m+++m++;

最近有位不相识的朋友发email给我,问为什么在某个c++系统里,下面表达式打印出两个4,而不是4和5:

a=4;cout<

c++不是规定<<操作左结合吗?是c++书上写错了,还是这个系统的实现有问题?

要弄清这些,需要理解的一个问题是:如果程序里某处修改了一个变量(通过赋值、增量/减量操作等),什么时候从该变量能够取到新值?有人可能说,“这算什么问题!我修改了变量,再从这个变量取值,取到的当然是修改后的值!”其实事情并不这么简单。

c/c++语言是“基于表达式的语言”,所有计算(包括赋值)都在表达式里完成。“x=1;”就是表达式“x=1”后加表示语句结束的分号。要弄清程序的意义,首先要理解表达式的意义,也就是:1)表达式所确定的计算过程;2)它对环境(可以把环境看作当时可用的所有变量)的影响。如果一个表达式(或子表达式)只计算出值而不改变环境,我们就说它是引用透明的,这种表达式早算晚算对其他计算没有影响(不改变计算的环境。当然,它的值可能受到其他计算的影响)。如果一个表达式不仅算出一个值,还修改了环境,就说这个表达式有副作用(因为它多做了额外的事)。a++就是有副作用的表达式。这些说法也适用于其他语言里的类似问题。

现在问题变成:如果c/c++程序里的某个表达式(部分)有副作用,这种副作用何时才能实际体现到使用中?为使问题更清楚,我们假定程序里有代码片段“...a[i]++...a[j]...”,假定当时i与j的值恰好相等(a[i]和a[j]正好引用同一数组元素);假定a[i]++确实在a[j]之前计算;再假定其间没有其他修改a[i]的动作。在这些假定下,a[i]++对a[i]的修改能反映到a[j]的求值中吗?注意:由于i与j相等的问题无法静态判定,在目标代码里,这两个数组元素访问(对内存的访问)必然通过两段独立代码完成。现代计算机的计算都在寄存器里做,问题现在变成:在取a[j]值的代码执行之前,a[i]更新的值是否已经被(从寄存器)保存到内存?如果了解语言在这方面的规定,这个问题的答案就清楚了。

程序语言通常都规定了执行中变量修改的最晚实现时刻(称为顺序点、序点或执行点)。程序执行中存在一系列顺序点(时刻),语言保证一旦执行到达一个顺序点,在此之前发生的所有修改(副作用)都必须实现(必须反应到随后对同一存储位置的访问中),在此之后的所有修改都还没有发生。在顺序点之间则没有任何保证。对c/c++语言这类允许表达式有副作用的语言,顺序点的概念特别重要。

现在上面问题的回答已经很清楚了:如果在a[i]++和a[j]之间存在一个顺序点,那么就能保证a[j]将取得修改之后的值;否则就不能保证。

c/c++语言定义(语言的参考手册)明确定义了顺序点的概念。顺序点位于:

1.每个完整表达式结束时。完整表达式包括变量初始化表达式,表达式语句,return语句的表达式,以及条件、循环和switch语句的控制表达式(for头部有三个控制表达式);

2.运算符&&、、?:和逗号运算符的第一个运算对象计算之后;

3.函数调用中对所有实际参数和函数名表达式(需要调用的函数也可能通过表达式描述)的求值完成之后(进入函数体之前)。

假设时刻ti和ti+1是前后相继的两个顺序点,到了ti+1,任何c/c++系统(vc、bc等都是c/c++系统)都必须实现ti之后发生的所有副作用。当然它们也可以不等到时刻ti+1,完全可以选择在时段[t,ti+1]之间的任何时刻实现在此期间出现的副作用,因为c/c++语言允许这些选择。

前面讨论中假定了a[i]++在a[i]之前做。在一个程序片段里a[i]++究竟是否先做,还与它所在的表达式确定的计算过程有关。我们都熟悉c/c++语言有关优先级、结合性和括号的规定,而出现多个运算对象时的计算顺序却常常被人们忽略。看下面例子:

(a+b)(c+d)fun(a++,b,a+5)

这里“”的两个运算对象中哪个先算?fun及其三个参数按什么顺序计算?对第一个表达式,采用任何计算顺序都没关系,因为其中的子表达式都是引用透明的。第二个例子里的实参表达式出现了副作用,计算顺序就非常重要了。少数语言明确规定了运算对象的计算顺序(java规定从左到右),c/c++则有意不予规定,既没有规定大多数二元运算的两个对象的计算顺序(除了&&、和,),也没有规定函数参数和被调函数的计算顺序。在计算第二个表达式时,首先按照某种顺序算fun、a++、b和a+5,之后是顺序点,而后进入函数执行。

不少书籍在这些问题上有错(包括一些很流行的书)。例如说c/c++先算左边(或右边),或者说某个c/c++系统先计算某一边。这些说法都是错误的!一个c/c++系统可以永远先算左边或永远先算右边,也可以有时先算左边有时先算右边,或在同一表达式里有时先算左边有时先算右边。不同系统可能采用不同的顺序(因为都符合语言标准);同一系统的不同版本完全可以采用不同方式;同一版本在不同优化方式下,在不同位置都可能采用不同顺序。因为这些做法都符合语言规范。在这里还要注意顺序点的问题:即使某一边的表达式先算了,其副作用也可能没有反映到内存,因此对另一边的计算没有影响。

回到前面的例子:“谁知道下面c语句给n赋什么值?”

m=1;n=m+++m++;

正确回答是:不知道!语言没有规定它应该算出什么,结果完全依赖具体系统在具体上下文中的具体处理。其中牵涉到运算对象的求值顺序和变量修改的实现时刻问题。对于:

cout<

我们知道它是

(cout.operator<<(a++)).operator<<(a);

的简写。先看外层函数调用,这里需要算出所用函数(由加下划线的一段得到),还需要计算a的值。语言没有规定哪个先算。如果真的先算函数,这一计算中出现了另一次函数调用,在被调函数体执行前有一个顺序点,那时a++的副作用就会实现。如果是先算参数,求出a的值4,而后计算函数时的副作用当然不会改变它(这种情况下输出两个4)。当然,

这些只是假设,实际应该说的是:这种东西根本不该写,讨论其效果没有意义。

有人可能说,为什么人们设计c/c++时不把顺序规定清楚,免去这些麻烦?c/c++语言的做法完全是有意而为,其目的就是允许编译器采用任何求值顺序,使编译器在优化中可以根据需要调整实现表达式求值的指令序列,以得到效率更高的代码。像java那样严格规定表达式的求值顺序和效果,不仅限制了语言的实现方式,还要求更频繁的内存访问(以实现副作用),这些可能带来可观的效率损失。应该说,在这个问题上,c/c++和java的选择都贯彻了它们各自的设计原则,各有所获(c/c++潜在的效率,java更清晰的程序行为),当然也都有所失。还应该指出,大部分程序设计语言实际上都采用了类似c/c++的规定。

讨论了这么多,应该得到什么结论呢?c/c++语言的规定告诉我们,任何依赖于特定计算顺序、依赖于在顺序点之间实现修改效果的表达式,其结果都没有保证。程序设计中应该贯彻的规则是:如果在任何“完整表达式”(形成一段由顺序点结束的计算)里存在对同一“变量”的多个引用,那么表达式里就不应该出现对这一“变量”的副作用。否则就不能保证得到预期结果。注意:这里的问题不是在某个系统里试一试的问题,因为我们不可能试验所有可能的表达式组合形式以及所有可能的上下文。这里讨论的是语言,而不是某个实现。总而言之,绝不要写这种表达式,否则我们或早或晚会某种环境中遇到麻烦。

后记:去年参加一个学术会议,看到有同行写文章讨论某个c系统里表达式究竟按什么顺序求值,并总结出一些“规律”。从讨论中了解到某“程序员水平考试”出了这类题目。这使我感到很不安。今年给一个教师学习班讲课,发现许多专业课教师也对这一基本问题也不甚明了,更觉得问题确实严重。因此整理出这篇短文供大家参考。

后后记:4年多过去了,许多新的和老的教科书仍然在不厌其烦地讨论在c语言里原本并无意义的问题(如本文所指出的)。希望学习和使用c语言的人不要陷入其中。

==============================

如果一个表达式的结果依赖于操作数的求值顺序,那这个表达式的行为(即结果)是无定义的。而使用标准没有定义的行为是错误的。所以应该修改表达式,使其与操作数的求值顺序无关。

C语言运算符的结合性详细分析

C语言运算符的结合性分析 吴琼( 鄂州大学计算机系, 湖北鄂州) C 语言与其他高级语言相比, 一个显著的特点就是其运算符特别丰富, 共有34 种运算符。C 语言将这34 种运算符规定了不同的优先级别和结合性。优先级是用来标识运算符在表达式中的运算顺序的, 在求解表达式的值的时候, 总是先按运算符的优先次序由高到低进行操作, 可是, 当一个运算对象两侧的运算符优先级别相同时, 则按运算符的结合性来确定表达式的运算顺序。 运算符的结合性指同一优先级的运算符在表达式中操作的组织方向, 即: 当一个运算对象两侧运算符的优先级别相同时, 运算对象与运算符的结合顺序, C 语言规定了各种运算符的结合方向( 结合性) 。大多数运算符结合方向是“自左至右”, 即: 先左后右, 例如a- b+c, b 两侧有- 和+两种运算符的优先级相同, 按先左后右结合方向, b 先与减号结合, 执行a- b 的运算, 再执行加c 的运算。除了自左至右的结合性外, C 语言有三类运算符参与运算的结合方向是从右至左。即: 单目运算符, 条件运算符, 以及赋值运算符。关于结合性的概念在其他高级语言中是没有的, 这是C语言的特点之一,特别是从右至左结合性容易出错, 下面通过几个具体的运算符来剖析C 语言运算符的结合性。 若a 是一个变量, 则++a 或a++和- - a 或a- - 分别称为前置加或后置加运算和前置减或后置减运算, 且++a 或a++等价于a=a+1, - - a 或a- - 等价于a=a- 1, 即都是使该变量的值增加1 或减少1。由此可知, 对一个变量实行前置或后置运算, 其运算结构是相同的, 但当它们与其他运算结合在一个表达式中时, 其运算值就不同了。前置运算是变量的值先加1 或减1, 然后将改变后的变量值参与其他运算, 如x=5; y=8; c=++x*y; 运算后, c 的值是48,x 的值是6,y 的值是8。而后置运算是变量的值先参与有关运算, 然后将变量本身的值加1 减1, 即参加运算的是该变量变化前的值。如x=5; y=8; c=x++*y;运算后, c 的值是40,x 的值是6, y 的值是8。值得注意的是, 前置、后置运算只能用于变量, 不能用于常量和表达式, 且结合方向是从右至左。如当i=6 时, 求- i++的值和i 的值。由于“- ”(负号) “++”为同一个优先级, 故应理解为- (i++), 又因是后置加, 所以先有- i++的值为- 6, 然后i 增值1 为7, 即i=7。 例1 main() {int a=3,b=5,c; c=a*b+++b; printf ( “c=%d”, c);} 要得出c 的值, 首先要搞清+++的含义。++运算符的结合方向是自右向左的, 如果将表达式理解为:c=a*b+(++b);实际上C 编译器将表达式处理为:c=(a*b++)+b, 因为C 编译器总是从左至右尽可能多地将若干个字符组成一个运算符, 如i+++j 等价于(i++)+j。接下来是解决a*b++的问题, 因为++运算符的运算对象只能是整型变量而不能是表达式或常数, 所以a*b++显然是a*(b++)而非(a*b)++, 因此整个表达式就是c=(a*(b++))+b。 例2 main() { int i=1,j; j=i+++i+++i++; printf( “i=%d,j=%d\n”, i,j);} 例3 main() { int i=1,m; m=++i+++i+++i; printf( “i=%d,m=%d\n”, i,m);}

几种运算符优先级

几种运算符优先级: ①!(非) ②算术运算符:()、*、/、%(求余)、+、- ③关系运算符:<、<=、>、>=、==、!= ④逻辑运算符{&&、||} ⑤赋值运算符:= printf(“%d”,4+3>5||5<9); 1 1)算术运算符的结果是计算后的数 a/b: a与b是两个操作数,/是运算符,当两个操作数都是整数,其结果则为整数;若其中之一是实型数,其结果则为实型数。printf(“%d”, 5/2);2 5.0/2=2.5 %(求余):规定其两个操作数都是整数 5%2=1 2)关系运算符的结果是逻辑真(1)或逻辑假(0) Int x=4,y=5; printf(“%d”, (x==y));0 printf(“%d”, (x==5));0 printf(“%d”, (x=5));5

3)逻辑运算符(!&& ||):的结果是逻辑真(1)或逻辑假(0) &&:两者为真则为真,其余则为假 ||:只要一个为真则为真 注意:凡是不为零的数则视为真 printf(“%d”, !4);0 printf(“%d”, 4&&5);1 printf(“%d”, 4&&0);0 printf(“%d”, 4||5);1 printf(“%d”, 4||0);1

复合的赋值运算符:= a*=a------------------a=a*a a+=a------------------a=a+a a/=a------------------a=a/a 规定:复合的赋值运算符就按自右向左的原则计算的,有多少个复合的赋值运算符就有多少步计算 Int a=5; printf("%d",a*=a+=a);100 100 50 a+=a ---a=a+a=5+5=10 a*=a-----a=a*a=100

C语言符号优先级

附录2 C语言中的运算符及其优先级 优先级运算符名称或含义使用形式结合方向说明 1 [] 数组下标数组名[常量表达式] 左到右() 圆括号 (表达式)/函数名 (形参表) . 成员选择(对象)对象.成员名 -> 成员选择(指针)对象指针->成员名 2 - 负号运算符-表达式 右到左 单目运算符(类型) 强制类型转换(数据类型)表达式 ++ 自增运算符++变量名/变量名++ 单目运算符-- 自减运算符--变量名/变量名-- 单目运算符* 取值运算符*指针变量单目运算符& 取地址运算符&变量名单目运算符! 逻辑非运算符!表达式单目运算符~ 按位取反运算符~表达式单目运算符sizeof 长度运算符sizeof(表达式) 3 / 除表达式/表达式 左到右 双目运算符* 乘表达式*表达式双目运算符% 余数(取模) 整型表达式/整型表 达式 双目运算符 4 + 加表达式+表达式 左到右 双目运算符- 减表达式-表达式双目运算符 5 << 左移变量<<表达式 左到右 双目运算符>> 右移变量>>表达式双目运算符 6 > 大于表达式>表达式 左到右 双目运算符>= 大于等于表达式>=表达式双目运算符< 小于表达式<表达式双目运算符<= 小于等于表达式<=表达式双目运算符 7 == 等于表达式==表达式 左到右 双目运算符!= 不等于表达式!= 表达式双目运算符 8 & 按位与表达式&表达式左到右双目运算符 9 ^ 按位异或表达式^表达式左到右双目运算符 10 | 按位或表达式|表达式左到右双目运算符 11 && 逻辑与表达式&&表达式左到右双目运算符 12 || 逻辑或表达式||表达式左到右双目运算符 13 ?: 条件运算符表达式1? 表达式2: 表达式3 右到左三目运算符 14 = 赋值运算符变量=表达式 右到左/= 除后赋值变量/=表达式 *= 乘后赋值变量*=表达式 %= 取模后赋值变量%=表达式 306

运算符的优先级顺序

附录:C语言运算符及优先级 优先级运算符含义运算符类型结合方向 15 ()圆括号单目自左向右 [] 下标运算符 —> 指向结构体成员运算符 、结构体成员运算符 14 !逻辑非运算符 自右向左 ~ 按位取反运算符 ++ 自增运算符 -- 自减运算符

- 负号运算符 (类型)类型转换运算符 * 指针运算符 & 地址运算符 Sizeof 长度运算符 13 * 乘法运算符双目自左向右 / 除法运算符 % 求余运算符 12 + 加法运算符 - 减法运算符 11 << 左移运算

符 >> 右移运算符 10 <、<=、>、>= 关系运算符 9 == 等于运算符 != 不等于运算符 8 & 按位与运算符 7 ^ 按位异或运算符 6 | 按位或运算符 5 && 逻辑与运算符 4 || 逻辑或运算符 3 :条件运算符三目自右向左

2 =、+=、-=、*=、 /=、%=、>>=、 <<=、&=、^=、|= 赋值运算符双目 1 ,逗号运算符双目自左向右 括号成员第一; -> 全体单目第二; //所有的单目运算符比如++ -- +(正) -(负) 指针运算*& 乘除余三,加减四; //这个"余"是指取余运算即% 移位五,关系六; //移位运算符:<< >> ,关系:> < >= <= 等等于(与)不等排第七; //即== != 位与异或和位或; //这几个都是位运算: 位与(&)异或(^)位或(|) "三分天下"八九十; 逻辑或跟与 //逻辑运算符:|| 和 && 十二和十一; //注意顺序:优先级(||) 底于优先级(&&) 条件高于赋值, //三目运算符优先级排到 13 位只比赋值运算

运算符优先级及结合顺序

优先级运算符名称或含义使用形式结合方向说明1 [] 数组下标数组名[常量表达式] 左到右 () 圆括号 (表达式)/函数名(形 参表) . 成员选择(对象)对象.成员名 -> 成员选择(指针)对象指针->成员名 2 - 负号运算符-表达式 右到左 单目运算符 (类型) 强制类型转换(数据类型)表达式 ++ 自增运算符++变量名/变量名++ 单目运算符-- 自减运算符--变量名/变量名-- 单目运算符 * 取值运算符*指针变量单目运算符 & 取地址运算符&变量名单目运算符 ! 逻辑非运算符!表达式单目运算符 ~ 按位取反运算符~表达式单目运算符 sizeof 长度运算符sizeof(表达式) 3 / 除表达式/表达式 左到右 双目运算符 * 乘表达式*表达式双目运算符 % 余数(取模) 整型表达式/整型表 达式 双目运算符 4 + 加表达式+表达式 左到右 双目运算符 - 减表达式-表达式双目运算符 5 << 左移变量<<表达式 左到右 双目运算符 >> 右移变量>>表达式双目运算符 6 > 大于表达式>表达式

左到右 双目运算符 >= 大于等于表达式>=表达式双目运算符 < 小于表达式<表达式双目运算符 <= 小于等于表达式<=表达式双目运算符 7 == 等于表达式==表达式 左到右 双目运算符 != 不等于表达式!= 表达式双目运算符 8 & 按位与表达式&表达式左到右双目运算符 9 ^ 按位异或表达式^表达式左到右双目运算符 10 | 按位或表达式|表达式左到右双目运算符 11 && 逻辑与表达式&&表达式左到右双目运算符 12 || 逻辑或表达式||表达式左到右双目运算符 13 ?: 条件运算符 表达式1? 表达式2: 表达式3 右到左三目运算符 14 = 赋值运算符变量=表达式 右到左 /= 除后赋值变量/=表达式 *= 乘后赋值变量*=表达式 %= 取模后赋值变量%=表达式 += 加后赋值变量+=表达式 -= 减后赋值变量-=表达式 <<= 左移后赋值变量<<=表达式 >>= 右移后赋值变量>>=表达式 &= 按位与后赋值变量&=表达式 ^= 按位异或后赋值变量^=表达式 |= 按位或后赋值变量|=表达式 15 , 逗号运算符表达式,表达式,… 左到右 从左向右顺 序运算

C运算符优先级记忆口诀

优先级从上到下依次递减,最上面具有最高的优先级,逗号操作符具有最低的优先级。 所有的优先级中,只有三个优先级是从右至左结合的,它们是单目运算符、条件运算符、赋值运算符。其它的都是从左至右结合。 具有最高优先级的其实并不算是真正的运算符,它们算是一类特殊的操作。()是与函数相关,[]与数组相关,而->及.是取结构成员。 其次是单目运算符,所有的单目运算符具有相同的优先级,因此在我认为的真正的运算符中它们具有最高的优先级,又由于它们都是从右至左结合的,因此*p++与*(p++)等效是毫无疑问的。 接下来是算术运算符,*、/、%的优先级当然比+、-高了。 移位运算符紧随其后。 其次的关系运算符中,< <= > >=要比 == !=高一个级别,不大好理解。 所有的逻辑操作符都具有不同的优先级(单目运算符出外,!和~) 逻辑位操作符的"与"比"或"高,而"异或"则在它们之间。 跟在其后的&&比||高。 接下来的是条件运算符,赋值运算符及逗号运算符。 在C语言中,只有4个运算符规定了运算方向,它们是&&、| |、条件运算符及赋值运算符。 &&、| |都是先计算左边表达式的值,当左边表达式的值能确定整个表达式的值时,就不再计算右边表达式的值。如 a = 0 && b; &&运算符的左边位0,则右边表达式b就不再判断。 在条件运算符中。如a?b:c;先判断a的值,再根据a的值对b或c之中的一个进行求值。 赋值表达式则规定先对右边的表达式求值,因此使 a = b = c = 6;成为可能。 初——单——算,关——逻,条——赋——逗 断句如上。怎么记忆呢? 我是这样记忆的:“”内表示运算符的简称。 “初”次“单”独找你“算”账,(因为你和关羽有仇) “关”羽带着兵巡“逻”(因为你躲了起来) 你跑到别处了,隐姓埋名,“挑”着“豆腐”卖。(当了卖豆腐的):豆腐——实际上是“赋”“逗” ?2009-4-8 15:43 ?回复 我是这样记得: 一个自称黑的初学者连编程都不会还算什么黑客,把自己关起来反思吧,逻辑都没有条理,因为你不认真学!还找理由说因为天赋不够,真逗``

C语言运算符优级列表

C语言运算符优先级列表 运算符的优先级:C语言中,运算符的运算优先级共分为15 级。1 级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。 运算符的结合性:C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。例如算术运算符的结合性是自左至右,即先左后右。如有表达式x-y+z 则y 应先与“-”号结合,执行x-y 运算,然后再执行+z 的运算。这种自左至右的结合方向就称为“左结合性”。而自右至左的结合方向称为“右结合性”。最典型的右结合性运算符是赋值运算符。如x=y=z,由于“=”的右结合性,应先执行y=z 再执行x=(y=z)运算。C语言运算符中有不少为右结合性,应注意区别,以避免理解错误。 优先级运算符名称或含义使用形式结合方向说明 1 [] 数组下标数组名[常量表达式] 左到右() 圆括号 (表达式)/函数名(形 参表) . 成员选择(对象)对象.成员名 -> 成员选择(指针)对象指针->成员名 2 - 负号运算符-表达式 右到左 单目运算符(类型) 强制类型转换(数据类型)表达式 ++ 自增运算符++变量名/变量名++ 单目运算符-- 自减运算符--变量名/变量名-- 单目运算符* 取值运算符*指针变量单目运算符& 取地址运算符&变量名单目运算符! 逻辑非运算符!表达式单目运算符~ 按位取反运算符~表达式单目运算符sizeof 长度运算符sizeof(表达式) 3 / 除表达式/表达式 左到右 双目运算符* 乘表达式*表达式双目运算符% 余数(取模) 整型表达式/整型表 达式 双目运算符 4 + 加表达式+表达式 左到右 双目运算符- 减表达式-表达式双目运算符 5 << 左移变量<<表达式 左到右 双目运算符>> 右移变量>>表达式双目运算符 6 > 大于表达式>表达式左到右双目运算符 1 / 1

c语言运算符及其优先级汇总表口诀

C语言运算符及其优先级汇总表口诀 圆下箭头一顿号 非凡增减富强针地长 三乘除,四加减,五移位 千万别把鱼忘记,它在盛饭的厨子里 小灯大灯灯灯不等 爸喂鱼,舅疑惑,裸鸡也疑惑 十三姨,十四父,十五逗,兜到低 “圆下箭头一顿号”指的是第15级的运算符。其中圆指的是运算符(),下指的是下标运算符[],箭头指的是指向结构体成员运算符->,顿号指的是结构体成员运算符、“非凡增减富强针地长”指的是第14级的运算符。其中非指的是逻辑运算符!,凡指的是按位取反运算符~,增减指的是自增和自减运算符++和--,富指的是负号运算符-,强指的是类型转换运算符(类型),针指的是指针运算符*,地指的是地址运算符&,长指的是长度运算符Sizeof “三乘除,四加减,五移位” 指的是第13级到第11级的运算符。其中三四五并无实际意义,只是起区分级别而已。也可以想象三指的是第13级运算符。乘除指的是乘法运算符*和除法运算符/,加减指的是加法运算符+和减法运算符-,移位指的是左移运算符<<和右移运算符>> “千万别把鱼忘记,它在盛饭的厨子里”指的是求余运算符%,它位于盛饭的厨子里,即指和乘法运算符、除法运算符在一起。 “小灯大灯灯灯不等” 指的是第10级到第9级的运算符。其中小灯大灯指的是关系运算符<、<=、>和>=,灯灯指的是等于运算符==,不等指的是不等于运算符!= “爸喂鱼,舅疑惑,裸鸡也疑惑”指的是第8级到第4级的运算符。其中,爸喂鱼之指的是第8级的按位与运算符&,舅疑惑指的是第7级的按位异或运算符^和第6级的按位或运算符||,裸鸡也疑惑指的是第5级、第4级的逻辑与运算符&&和逻辑或运算符|| “十三姨,十四父,十五逗,兜到低”指的是第3级到第1级的运算符。其中,十三姨指的是条件运算符?: (三有双重含义,即指?:的优先级别是三,它的运算符类型也是三目,?难道不是姨即疑惑吗?),十四父的十四没有实际意义,父指的是赋值运算符=、+=、-=、*=、/=、%=、>>=、<<=、&=、^=和|= ,十五逗指的是第1级的运算符,兜到低指的是15级运算符以,结束。 附录:C语言运算符及优先级 优先级运算符含义运算符类型结合方向 15 ()圆括号单目自左向右 [] 下标运算符 —> 指向结构体成员运算符 、结构体成员运算符 14 !逻辑非运算符自右向左 ~ 按位取反运算符 ++ 自增运算符 -- 自减运算符 - 负号运算符 (类型)类型转换运算符 * 指针运算符

C#语言的42个运算符及15个优先级

C#语言的42个运算符及15个优先级(补充) 一、赋值运算符 赋值语句的作用是把某个常量或变量或表达式的值赋值给另一个变量。符号为‘=’。这里并不是等于的意思,只是赋值,等于用‘==’表示。 注意:赋值语句左边的变量在程序的其他地方必须要声明。 得已赋值的变量我们称为左值,因为它们出现在赋值语句的左边;产生值的表达式我们称为右值,因为她它们出现在赋值语句的右边。常数只能作为右值。 例如: count=5; total1=total2=0; 第一个赋值语句大家都能理解。 第二个赋值语句的意思是把0同时赋值给两个变量。这是因为赋值语句是从右向左运算的,也就是说从右端开始计算。这样它先total2=0;然后total1=total2;那么我们这样行不行呢? (total1=total2)=0; 这样是不可以的,因为先要算括号里面的,这时total1=total2是一个表达式,而赋值语句的左边是不允许表达式存在的。 二、算术运算符 在C语言中有两个单目和五个双目运算符。 符号功能 + 单目正 - 单目负 * 乘法 / 除法 % 取模 + 加法 - 减法 下面是一些赋值语句的例子,在赋值运算符右侧的表达式中就使用了上面的算术运算符: Area=Height*Width; num=num1+num2/num3-num4; 运算符也有个运算顺序问题,先算乘除再算加减。单目正和单目负最先运算。 取模运算符(%)用于计算两个整数相除所得的余数。例如: a=7%4; 最终a的结果是3,因为7%4的余数是3。 那么有人要问了,我要想求它们的商怎么办呢? b=7/4; 这样b就是它们的商了,应该是1。 也许有人就不明白了,7/4应该是1.75,怎么会是1呢?这里需要说明的是,当两个整

C语言运算符优先级 详细列表

C语言运算符优先级详细列表 运算符的优先级:C语言中,运算符的运算优先级共分为15 级。1 级最高,15级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。 运算符的结合性:C语言中各运算符的结合性分为两种,即左结合性(自左至右)和右结合性(自右至左)。例如算术运算符的结合性是自左至右,即先左后右。如有表达式x-y+z 则y 应先与“-”号结合,执行x-y 运算,然后再执行+z 的运算。这种自左至右的结合方向就称为“左结合性”。而自右至左的结合方向称为“右结合性”。最典型的右结合性运算符是赋值运算符。如x=y=z,由于“=”的右结合性,应先执行y=z 再执行x=(y=z)运算。C语言运算符中有不少为右结合性,应注意区别,以避免理解错误。 优先级运算符名称或含义使用形式结合方向说明 1 [] 数组下标数组名[常量表达式] 左到右() 圆括号 (表达式)/函数名(形 参表) . 成员选择(对象)对象.成员名 -> 成员选择(指针)对象指针->成员名 2 - 负号运算符-表达式 右到左 单目运算符(类型) 强制类型转换(数据类型)表达式 ++ 自增运算符++变量名/变量名++ 单目运算符-- 自减运算符--变量名/变量名-- 单目运算符* 取值运算符*指针变量单目运算符& 取地址运算符&变量名单目运算符! 逻辑非运算符!表达式单目运算符~ 按位取反运算符~表达式单目运算符sizeof 长度运算符sizeof(表达式) 3 / 除表达式/表达式 左到右 双目运算符* 乘表达式*表达式双目运算符% 余数(取模) 整型表达式/整型表 达式 双目运算符 4 + 加表达式+表达式左到右双目运算符

C++运算符的优先级与结合性

c/c++运算符的优先级和结合性 内容导读:遍历了15个级别之后,让我们再来总结一下。其中我们可以看出这样两个规律:规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符; 规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算... 遍历了15个级别之后,让我们再来总结一下。其中我们可以看出这样两个规律: 规律一、按照操作数个数来区分,一元运算符高于二元运算符,二元运算符高于三元运算符; 规律二、按照运算符的作用来区分,级别最高的是那些不是严格意义上的运算符,次之是算术运算符,位移运算符,关系运算符,位运算符,逻辑运算符,赋值运算符。 此外还有两特别的地方需要注意: 一、同为关系运算符,但==和!=的级别低于其它四个; 二、第2组与第13组的操作符是右结合的,其它的都为左结合; 通过分类我们大大减少了需要记忆的内容,遇到使用操作符的时候,我们只需想想它们是什么类型的运算符就可以确定它们之间的相对优先级,从而避免一些不必要的错误。 ====================================================================== =================== 提起运算符的优先级,很多了解c++的过来人都会想:这有什么难的?不就是谁的优先级高就算谁么。确实如此,运算符的优先级不是一个大问题,但对于一个初学者来说,却经常容易在上面迷糊与犯错。而对于一个了解c++的人来说,我相信也会偶尔在上面摔倒,不信就继续往下读。 “优先级高的先运算”带来的困惑 c++中运算符的优先级有一张表,表里把运算符进行了分类,这张表是不需要死记硬背的,只要有个大致的轮廓就ok了。例如应该记住最低优先级是逗号运算符,其次是赋值运算符,再其次是三目运算符。而关系运算符的优先级高于逻辑运算符(不包括逻辑非运算),算术运算符的优先级高于关系运算符,象++和﹣﹣的优先级比前面几个都高,但最高的要属()了。知道这些后,你的脑海里一定有一条准则了:优先级高的先运算。那么下面看一个例子: intx=1,y=0; !x&&x+y&&++y;

运算符的优先级

第一种记忆方法: 你可以按照熟悉程度来记忆: 先乘除后加减:* / % 在第3级;+ - 在第4级; 括号仍旧是最优先的,和以前学习的概念一样,在第1级; 最第一级是逗号,组建逗号表达式用的。第15级; 我们还熟悉的是大于,小于,大于等于,小于等于,年年有鱼,六六大顺,那么在第6级; 顺便记忆不等于!= ==,在第7级; 逻辑或||和逻辑与&&要交叉记忆,长的像11的却在12级,另一个就在11级。 在我们这个表里,大部分都是双目运算符,那么现在来看看特殊的,单目运算符和三目运算符,单目运算符在第2级,三目运算符?:在第13级。 还有一个很熟悉的赋值号=,复合赋值号+=,地位很低,往往都是其他运算执行完毕后,才执行它,故在第14级。 经过一番努力,我们基本上记住了1,2,3,4,6,7,11,12,13,14,15级,初次记忆来说,已经很成功了。 第二种方法:记忆《秋夜打渔图》 秋夜打渔图 扩大成甲鱼,大小不等鱼;

位于一伙伙,渔火三服豆; 意义:渔夫捕鱼,有甲鱼,大小不等的鱼,都在一伙伙渔夫的手里,河面上有星星点点的渔火,还有丰收的大豆,整个呈现出丰收的景象; 1扩:代表括号; 2大:谐音,单,单目运算符; 3成:谐音:乘号; 4甲:谐音:加号; 5鱼:谐音:移动,左移右移; 6大小:代表大于号,小于号,还有大于等于号,小于等于号; 7不等鱼:代表不等于号和等于号; 8位于:谐音:按位与&; 9(位)一伙:谐音:按位异或^; 10(位)伙:谐音:按位或|; 11渔:谐音:逻辑与,&&; 12火:谐音:逻辑或,||; 13三:三目运算符?:; 14服:谐音:赋值运算符; 15豆:逗号运算符;

运算符的优先级和结合性-8页word资料

下面是C语言中所使用的运算符的优先级和结合性: 优先级运算符结合性 (最高) () [] -> . 自左向右 ! ~ ++ -- + - * & sizeof 自右向左 * / % 自左向右 + - 自左向右 << >> 自左向右 < <= > >= 自左向右 == != 自左向右 & 自左向右 ^ 自左向右 | 自左向右 && 自左向右 || 自左向右 ?: 自右向左 = += -= *= /= %= &= ^= |= <<= >>= 自右向左 (最低) , 自左向右 还有指针运算符、sizeof运算符、数组运算符[]等等 一、赋值运算符 赋值语句的作用是把某个常量或变量或表达式的值赋值给另一个变量。符号为‘=’。这里并不是等于的意思,只是赋值,等于用‘==’表示。 注意:赋值语句左边的变量在程序的其他地方必须要声明。 得已赋值的变量我们称为左值,因为它们出现在赋值语句的左边;产生值的表

达式我们称为右值,因为她它们出现在赋值语句的右边。常数只能作为右值。例如: count=5; total1=total2=0; 第一个赋值语句大家都能理解。 第二个赋值语句的意思是把0同时赋值给两个变量。这是因为赋值语句是从右向左运算的,也就是说从右端开始计算。这样它先total2=0;然后total1=total2;那么我们这样行不行呢? (total1=total2)=0; 这样是不可以的,因为先要算括号里面的,这时total1=total2是一个表达式,而赋值语句的左边是不允许表达式存在的。 二、算术运算符 在C语言中有两个单目和五个双目运算符。 符号功能 + 单目正 - 单目负 * 乘法 / 除法 % 取模 + 加法 - 减法 下面是一些赋值语句的例子,在赋值运算符右侧的表达式中就使用了上面的算术运算符:

C语言中的运算符及其优先级

附录2 C语言中的运算符及其优先级

同一优先级的运算符,运算次序由结合方向所决定。 由于C语言中运算符多,优先级复杂,难以记忆,针对上述运算符,我们可以归纳成几名口诀,以便于记忆:

优先级口诀 括号成员第一;括号运算符[]() 成员运算符. -> 全体单目第二;所有的单目运算符比如++ -- +(正) -(负) 指针运算*& 乘除余三,加减四;这个"余"是指取余运算即% 移位五,关系六;移位运算符:<< >> ,关系:> < >= <= 等 等于(与)不等排第七;即== != 位与异或和位或;这几个都是位运算: 位与(&)异或(^)位或(|) "三分天下"八九十; 逻辑或跟与;逻辑运算符:|| 和 && 十二和十一;注意顺序:优先级(||) 底于优先级(&&) 条件高于赋值, 三目运算符优先级排到 13 位只比赋值运算符和","高 逗号运算级最低!逗号运算符优先级最低 C优先级的口诀收藏 学习C语言也有一段时间了,感觉C语言的运算符优先级很难记住,特别是对于初学者而言! 也许你会说没有记住没关系,用括号来改变优先级就可以了。但是很多情况下,因为依赖括号很容易导致程序可读性差,当然我不是反对加括号,只是提倡恰到好处。总之,还是记住好些,读别人的程序也方便点。近来翻看了一下优先级,感觉还是有规律可循的,拿来和大家分享,希望对大家有帮助! 先给出C语言的运算符优先级表: 第一、像() [] -> .之类的理所当然是最优先的,其实它们压根也不算什么运算符了 第二、除了上面的四种运算符之外,接下来就是单目运算符,也就是! ~ ++ -- - (type) * & sizeof 了。记住它们的顺序可是自右向左啊!其实结合实例是很容易理解的,比如i++等。 第三、跟着就是双目运算符了,也是C语言运算符优先级中最容易让人混淆的地方了。其实也没有那么可怕,你认真观察就会发现。在双目运算符中,算术运算符优先级最高,然后是移位运算符,接着是关系运算符,再着是逻辑运算符。不过这边需要说的是,在关系运算符中,< <= > >=比== !=的优先级来得高。此外,在逻辑运算符中,与运算又比或运算优先级来得高,异或则处于二者之间。同样的,你可以类比出&&与||的优先级关系. 第四、在双目操作符之后,就是三目操作符了,没有什么好说的了。 第五、然后是赋值操作符,你也许会把赋值操作符与三目运算符的优先级搞混。没有关系,我想你一定写过这样的语句(如果没有,请你记住!):max = (a>b)?a:b; ,从这个语句里,你就不难记住赋值运算符为什么比三目运算符的优先级低了! 第六、逗号运算符是分割各个子语句的(感觉这么说有点不准确,不过我想大家会明白我的意思的),自然优先级最低了,我想这个应该不是很容易混淆的。

《C语言优先级》Word文档

学习C语言也有一段时间了,感觉C语言的运算符优先级很难记住,特别是对于初学者而言! 也许你会说没有记住没关系,用括号来改变优先级就可以了。但是很多情况下,因为依赖括号很容易导致程序可读性差,当然我不是反对加括号,只是提倡恰到好 处。总之,还是记住好些,读别人的程序也方便点。近来翻看了一下优先级,感觉还是有规律可循的,拿来和大家分享,希望对大家有帮助! 先给出C语言的运算符优先级表: C语言运算符优先级表(由上至下,优先级依次递减)

第一、像() [] -> .之类的理所当然是最优先的,其实它们压根也不算什么运算符了 第二、除了上面的四种运算符之外,接下来就是单目运算符,也就是! ~ ++ -- - (type) * & sizeof 了。记住它们的顺序可是自右向左啊!其实结合实例是很容易理解的,比如i++等。

第三、跟着就是双目运算符了,也是C语言运算符优先级中最容易让人混淆的地方了。其实也没有那么可怕,你认真观察就会发现。在双目运算符中,

算术运算符优先级最高,然后是移位运算符,接着是关系运算符,再着是逻辑运算符。不过这边需要说的是,在关系运算符中,< <= > >=比== !=的优先级来得高。此外,在逻辑运算符中,与运算又比或运算优先级来得高,异或则处于二者之间。同样的,你可以类比出&&与||的优先级关系. 第四、在双目操作符之后,就是三目操作符了,没有什么好说的了。 第五、然后是赋值操作符,你也许会把赋值操作符与三目运算符的优先级搞混。没有关系,我想你一定写过这样的语句(如果没有,请你记住!):max = (a>b)?a:b; ,从这个语句里,你就不难记住赋值运算符为什么比三目运算符的优先级低了! 第六、逗号运算符是分割各个子语句的(感觉这么说有点不准确,不过我想大家会明白我的意思的),自然优先级最低了,我想这个应该不是很容易混淆的。 总结一下,按运算符优先级从高到低:单目运算符->双目运算符->三目运算符->赋值运算符->逗号运算符 特别在双目运算符中,按运算符优先级从高到低:算术运算符->移位运算符->关系运算符(其中== 和 !=优先级又较低)->逻辑运算符(按位与-〉按位异或-〉按位或-〉逻辑与-〉逻辑或)! Examples: ++p->len = ++(p->len) *p->str++ = *(p->str)++ = *((p->str)++) *p++->str = *(p++)->str = *((p++)->str) msb<<4+lsb = msb<<(4+lsb) *p.f = *(p.f) val&mask!=0 = val&(mask!=0) (注:素材和资料部分来自网络,供参考。请预览后才下载,期待你的好评与关注!)

运算符优先级和结合性

C语言运算符优先级表(由上至下,优先级依次递减) 1、() [] -> .之类的理所当然是最优先的,其实它们压根也不算什么运算符了。 2、除了上面的四种运算符之外,接下来就是单目运算符,也就是! ~ ++ -- - (type) * & sizeof 了。记住它们的顺序可是自右向左啊!其实结合实例是很容易理解的,比如i++等。 3、接着是双目运算符了,也是C语言运算符优先级中最容易让人混淆的地方了。其实也没有那么可怕,你认真观察就会发现。在双目运算符中,算术运算符优先级最高,然后是移位运算符,接着是关系运算符,再着是逻辑运算符。不过这边需要说的是,在关系运算符中,< <= > >=比== !=的优先级来得高。此外,在逻辑运算符中,与运算又比或运算优先级来得高,异或则处于二者之间。同样的,你可以类比出&&与||的优先级关系。 4、在双目操作符之后,就是三目操作符了,没有什么好说的了。

5、然后是赋值操作符,你也许会把赋值操作符与三目运算符的优先级搞混。没有关系,我想你一定写过这样的语句(如果没有,请你记住!):max = (a>b)?a:b; ,从这个语句里,你就不难记住赋值运算符为什么比三目运算符的优先级低了! 6、逗号运算符是分割各个子语句的(感觉这么说有点不准确,不过我想大家会明白我的意思的),自然优先级最低了,我想这个应该不是很容易混淆的。 总结一下,按运算符优先级从高到低:单目运算符->双目运算符->三目运算符->赋值运算符->逗号运算符特别在双目运算符中,按运算符优先级从高到低:算 术运算符->移位运算符->关系运算符(其中== 和 !=优先级又较低)->逻辑运算符(按位与-〉按位异或-〉按位或-〉逻辑与-〉逻辑或)! 运算符的结合性指同一优先级的运算符在表达式中操作的组织方向, 即: 当一 个运算对象两侧运算符的优先级别相同时, 运算对象与运算符的结合顺序, C 语言规定了各种运算符的结合方向( 结合性) 。大多数运算符结合方向是“自左至右”, 即: 先左后右, 例如a- b+c, b 两侧有- 和+两种运算符的优先级相同, 按先左后右结合方向, b 先与减号结合, 执行a- b 的运算, 再执行加c 的运算。除了自左至右的结合性外, C 语言有三类运算符参与运算的结合方向是从右至左。即: 单目运算符, 条件运算符, 以及赋值运算符。关于结合性的概念在其他高级语言中是没有的, 这是C语言的特点之一。 ++a 或a++和--a 或a--分别称为前置加或后置加运算和前置减或后置减运算, 都是单目运算符。值得注意的是, 前置、后置运算只能用于变量, 不能用于常量和表达式, 且结合方向是从右至左。如当i=6 时, 求- i++的值和i 的值。由于“- ”(负号) “++”为同一个优先级, 故应理解为- (i++),又因是后置加, 所以先有-i++的值为-6, 然后i 增值1 为7, 即i=7。 例1 main() { int a=3,b=5,c; c=a*b+++b; printf ( “c=%d”, c); }

VB各种运算符及优先级

运 算符 作用区别示例结果& 将两 个字符串 拼接起来 连接符两旁的操作数不管是字符型还是 数值型,系统先将操作数转换成字符,然后再 连接。 "123"&55 "abc"+12 "12355" "abc12" + 连接符两旁的操作数均为字符型;若均为 数值型则进行算术加法运算;若一个为数字字 符型,一个数值型,则自动将数字字符转换为 数值,然后进行算术加;若一个为非数字字符 型,一个数值型,则出错。 "123"+55 "abc"+12 178 出错 Like运算符 通配符说明用法 ?任何单一字符Chi可写成c?i * 任何个数字符,包括空字符Chi可写成C* # 任何一个数字(0~9)Ch98可写成Ch## [] []中任何一个单字符Chi可写成C[a-z]I,还可写成C[ag-z] [!] 不在[!]中的任何单一字符Chi可写成C[!a-gi-z] B = “a1a” Like “a#a” ‘返回True

B = “D” Like “[A-Z]” ‘返回True B = “D” Like “[!A-Z]” ‘返回False B = “CAT1234Hdrg” Like “C?T*” ‘返回True B = “BAT1234Hdrg” Like “C?T*” ‘返回False 关系运算符 运算符含义示例结果= 等于"ABCDE"="ABR" False > 大于"ABCDE">"ABR" False >= 大于等于"bc">="大小" False < 小于23<3 False <= 小于等于"23"<="3" True <> 不等于"abc"<>"ABC" True Like 字符串匹配"ABCDEFG" Like "*DE*" True Is 对象引用比较 注意: 1)如果两个操作数都是数值型,则按其大小比较 2)如果两个操作数都是字符型,则按字符的ASCII码值从左到右一一比较3)汉字字符大于西文字符 4)关系运算符的优先级相同 逻辑运算符 运算符含义 优 先级 说明示例结果 Not 取反,逻 辑非 1 当操作数为假时,结果为 真 Not F Not T T F And 逻辑与 2 两个操作数均为真时,结 果才为真T And T F And F T And F F And T T F F F Or 逻辑或 3 两个操作数中有一个为 真时,结果为真T Or T F Or F T Or F F Or T T F T T

运算符优先级

运算符是表达式很重要的一部分,它指示对表达式中的操作数进行什么样的运算,如+、-、*、/、%等。根据运算符所需操作数的个数,可以把运算符分为以下3类。本节介绍运算符的知识点。 一元运算符:只带有一个操作数并使用前缀表示法(如--x)或后缀表示法(如x++),如++、- -等运算符。 二元运算符:带有两个操作数并且全都使用中缀表示法(如x+y),如+、-、*、/等运算符。 三元运算符:带有3个操作数并使用中缀表示法,如?: 运算符。 注意:C#语言只包含一个三元运算符:?:。 5.2.1 运算符优先级 算术表达式是最为常见的一种表达式。它由操作数和运算符组成,而且这些运算符之间是存在一定优先级的,如*运算符的优先级就大于+运算符的优先级。C#语言中的运算符一样,也存在优先级。在计算表达式的值时,也必须遵循运算符的优先级的规则。 特别地,当表达式包括多个运算符时,运算符的优先级控制各个运算符的计算顺序。对于x+y*z表达式而言,该表达式首先计算y*z表达式的值,然后再计算y*z表达式的结果与x 的和。即该表达式等价于x+(y*z)表达式,那是因为*运算符的优先级大于+运算符的优先级。根据运算符的优先级可以把C#中的运算符分为以下14类,如表5.2所示。 表5.2 C#中的运算符表 注意:表5.2是按照从最高到最低的优先级顺序列举了C#语言的所有运算符。

当操作数出现在具有相同优先级的两个运算符之间时,运算符的顺序与运算符本身特性相关,具体说明如下所示。 除了赋值运算符外,所有的二元运算符都是从左向右执行运算。如"x+y+z"表达式按照"(x+y)+z"表达式进行计算。 赋值运算符和?:条件运算符是从右向左执行运算。如x=y=z表达式按照x=(y=z)表达式进行计算

C语言运算符优先级和结合性一览表

所谓优先级就是当一个表达式中有多个运算符时,先计算谁,后计算谁。这个其实我们在小 学学算术的时候就学过,如 但是C语言中的运算符已经远不止四则运算中的加减乘除了,还有其他很多运算符。当它们出现在同一个表达式中时先计算谁后计算谁呢?所以本节还是有必要讲一下的。最后我还会将所有运算符展示出来,然后告诉你哪个优先级高、哪个优先级低。 首先不需要专门记忆,也没有必要。因为作为初学者,哪个优先级高、哪个优先级低我们很难记住。就算死记硬背记住了,时间长不用也会忘记。所以当一个表达式中有多个运算符时,如果不知道哪个优先级高哪个优先级低就查一下优先级表,附录E有一个运算符优先级表。此外用的时间长了自然而然就记住了,这样记才会记得深刻。 而且事实上在编程的时候也不需要考虑优先级的问题。因为如果不知道优先级高低的话,加 根据运算符的优先级,这条语句完全可以写成: 但是第一种写法别人一看就知道先计算谁后计算谁。 而且加圆括号也是一种编程规范,因为程序不只是写给自己看。

此外运算符还有“目”和“结合性”的概念,这个很简单。“目”就是“眼睛”的意思,一 3+2 3 和2 就像它的两只眼睛,所以这个运算符是双目的。 C 它就只有一只眼睛,所以是单目的。整个C语言中只有一个三目运算符, 这个稍后讲到条件语句的时候再介绍。关于“目”大家了解一下就行了。 那么“结合性”是什么呢?上面讲的优先级都是关于优先级不同的运算符参与运算时先计算谁后计算谁。但是如果运算符的优先级相同,那么先计算谁后计算谁呢?这个就是由“结合性”决定的。 比如乘和除的优先级相同,但是计算的时候是从左往右,即先计算乘再计算除,所以乘和除的结合性就是从左往右。就是这么简单! C语言中大多数运算符的结合性都是从左往右,只有三个运算符是从右往左的。一个是单目 运算符,另一个是三目运算符,双目运算符中只有赋值运算符的结合性是从右往左的,其他的都是从左往右。运算符的“结合性”也不要死记,在不断使用中就记住了。 运算符优先级和结合性一览表

附录3 C语言中的运算符及其优先级

附录3 C语言中的运算符及其优先级 306 附录3 C语言中的运算符及其优先级

附录3 C语言中的运算符及其优先级 说明: 同一优先级的运算符,运算次序由结合方向所决定。 由于C语言中运算符多,优先级复杂,难以记忆,针对上述运算符,我们可以归纳成几名口诀,以便于记忆: 优先级口诀 括号成员第一;括号运算符[]() 成员运算符. -> 全体单目第二;所有的单目运算符比如++ -- +(正) -(负) 指针运算*& 乘除余三,加减四;这个"余"是指取余运算即% 移位五,关系六;移位运算符:<< >> ,关系:> < >= <= 等 等于(与)不等排第七;即== != 位与异或和位或;这几个都是位运算: 位与(&)异或(^)位或(|) "三分天下"八九十; 逻辑或跟与;逻辑运算符:|| 和 && 十二和十一;注意顺序:优先级(||) 底于优先级(&&) 条件高于赋值, 三目运算符优先级排到 13 位只比赋值运算符和","高 逗号运算级最低!逗号运算符优先级最低 醋坛酸味灌 味落跳福豆 共44个运算符 醋-初等,4个:( ) [ ] -> 指向结构体成员. 结构体成员 坛-单目,9个:! ~ ++ -- -负号(类型) *指针&取地址sizeof长度(结合方向:自右向左) 酸-算术,5个:* / % + -减 味-位移,2个:<< >> 灌-关系,6个:< <= > >= == 等于!= 不等于 味-位逻,3个:& 按位与^ 按位异或| 按位或 落-逻辑,2个:&& 逻辑与|| 逻辑或 跳-条件,1个,三目:? : (结合方向:自右向左) 福-赋值,11个:= += -= *= /= %= >>= <<= &= ^= |= (结合方向:自右向左) 307

相关主题
文本预览
相关文档 最新文档