C之旅(一)运算符——优先级,结合性和求值顺序

本节主要讲基本运算符的优先级,结合性和求值顺序。
先看一个表达式- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))
记住你对它的运算过程,看完下面的内容之后,也许你会用不同的方式来看待这个表达式。

基本运算符 = + - * /

C中没有指数运算。
运算符操作的是操作数,操作数就是放在运算符两侧的东西。

(1) 赋值运算符 =

year = 2016; 读作将值2016赋给year,而非year等于2016。
=将2016赋给变量year,是从右到左的,即=具有右结合性。
2016 = year; 这种写法是错误的,不能给常量赋值。
那么,=的左边应该放什么样的对象?
答案是必须是一个存储位置。year是一个变量名,代表的是一个地址,这里可以存储值。
year可以被赋值,我们称这类可以被赋值的实体为可修改的左值。
右值指可以赋给可修改的左值的量,当然,右值就不必在乎可不可以修改了。

=运算符的操作数有哪些呢?

(2)加法运算符 +

+将两侧的值加到一起。
+的操作数可以是变量也可以是常量。

(3)减法运算符 –

-从它前面的数减去它后面的数。
-的操作数可以是变量也可以是常量。

(4)符号运算符 + -

先看一个表达式:
-(1990 - 2016)
第一个减号-和第二个减号-含义相同吗?
答案是不相同。
+ - 作用于两个操作数时称为二元算数运算符,当它们作用于一个操作数时,称为一元符号运算符。
-作用于一个操作数时,用于指示或改变其代数符号。
一元运算符+在C90标准才加进C中,这之前是不允许+1990这种语句的。一元运算符+不改变它的操作数的值或符号。

(5)乘法运算符 *

*将左右两个操作数相乘。
*的操作数可以是变量也可以是常量。

(6)除法运算符 /

在讲前面的运算符时,为什么一直强它们调操作数呢?因为有些运算符不能作用于某些类型,也有些运算符作用于不同的操作数结果不同。
/左边的值被右边的值除。
/作用于浮点数,结果为浮点数,如2.0/3.0的结果为0.666667(为什么不是0.666666?)
/作用于整型数,结果为整数,如2/3的结果为0,而不是0.6或0.7,因为自从C99之后,整数除法采用了趋零截尾的方式,直接截掉小数点后的数字。
2.0/3.0, 2/3结果都可知了,那么2.0/3或2/3.0的结果是什么?
先有一个这样的意识,如果算术运算符两侧操作数的类型不同,会引起类型转换。
2.0/3或2/3.0中,首先将整型值提升为浮点型,然后再做除法运算,结果为0.666667(为什么不是0.666666?)

既然是趋零结尾,那么C中怎么实现四舍五入呢?

可以巧妙的利用趋零结尾的方式,对正数a用(int)(a+0.5)方式,对负数a用(int)(a-0.5)的方式。

(7)运算符的优先级,优先级和求值顺序

下面表达式的结果是什么?运算顺序是怎样的?
- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))

按照我们正常计算的思维,会先算2*3,第一个加号之前的结果为-6,然后再算后面括号里表达式的值。

在计算上面的表达式之前,我们先来看一个简单的表达式,来解释一些概念。
2*3+4*5
想一下,在你刚刚计算的时候,什么时候用到了优先级?
当两个运算符共享同一个操作数的时,优先级决定了求值顺序。2*3+4*5中,4为+和*共享,优先级就规定先对4进行乘法运算,这保证两个*运算在+运算之前进行,在2*3+4*5这个表达式中,优先级的作用到此为止了。

接着考虑,2*3和4*5先计算哪个?
你可能会认为是先计算2*3,理由是加法运算符+的结合性。+作为二元运算符时,结合性是从左到右,所以先计算+的左边,再计算右边。如果你这样想,就对结合性理解有误了。

什么是运算符的结合性?
我们看表达式2*3+4*5-6*7,乘法运算过后,表达式简化为6 + 20 - 42,这时应该先计算6+20,再计算26-42,因为有相同优先级的+和-共享同一操作数20,所以+发挥了结合性的作用。记住,结合性适合于共享同一操作数的运算符(注意与优先级的作用进行区分)。在2*3+4*5中,两个*不共享同一操作数,而且先进行乘法运算,简化为6+20之后,没有操作数是共享的。所以上边的想法就有误了。

先计算哪个乘法?
2*3+4*5中,到底先进行哪个乘法运算呢?答案是不确定,看具体的实现,由设计者决定。特别需要注意的是,优先级只保证乘法在加法前进行,并不确定两个乘法哪个先进行。

了解了上面的概念,现在我们来看表达式
- (1 + 2) * 3 + (4 + 5 * (6 + 7 ))
根据优先级,先计算圆括号里的表达式,这里面有三个圆括号(),先计算哪个呢?
可以确定的是红色括号里的表达式在绿色括号里进行,但蓝色括号和绿色括号之间谁先被运算,依赖于实现。
注意,前半部分(1+2)运算完之后是-3*3,然后第一个3和它前面的一元符号运算符结合为-3,然后再乘以3。

时间: 2024-10-03 14:04:36

C之旅(一)运算符——优先级,结合性和求值顺序的相关文章

c/c++ 运算符 优先级 结合性 记录

1. ||  &&  是右结合性 2. ++ -- 是整个表达式运算结束或开始前计算的.不只是一个运算符后. int i=1,j; j=i+++i+++i++;    i=4,j=3; int i=1,m; m=++i+++i+++i;   i=4,m=12; 3.a+++b; 结果是(a++)+b还是a+(++b)呢?答案是前者,因为在遇到这种情况时,C编译器会将表达式按照从左往右的顺序尽量匹配出一个子表达式,所以当C编译器遇到a且后面有3个+号时,会首先尝试匹配a+++,当然这是没有意

二元运算符求值顺序问题

对于没有指定顺序的运算符来说,如果表达式指向并修改了同一对象,将会引发错误并产生未定义行为.如: int i = 0: cout << i << " " << ++i; // 未定义 经验: 拿不准时用括号 如果改变了一个运算对象的值,在表达式的其他地方就不要在使用这个运算对象(当改变运算对象的子表达式本身就是另外一个子表达式的运算对象时,是可以的 如:*++iter

【C知识点】C 运算符优先级和结合性y

1.C语言的运算符优先级有15个,如下图所示. 优先级 运算符 名称或含义 使用形式 结合方向 说明 1 [] 数组下标 数组名[常量表达式] 左到右 调用函数,数组 结构体成员选择符 () 圆括号 (表达式)/函数名(形参表)   . 成员选择(对象) 对象.成员名   -> 成员选择(指针) 对象指针->成员名   2 - 负号运算符 -表达式 右到左 单目运算符 优先级别仅此前者 (类型) 强制类型转换 (数据类型)表达式   ++ 自增运算符 ++变量名/变量名++ -- 自减运算符

PHP中运算符优先级

运算符优先级指定了两个表达式绑定得有多“紧密”.例如,表达式 1 + 5 * 3 的结果是 16 而不是 18 是因为乘号(“*”)的优先级比加号(“+”)高.必要时可以用括号来强制改变优先级.例如:(1 + 5) * 3 的值为 18. 如果运算符优先级相同,那运算符的结合方向决定了该如何运算.例如,"-"是左联的,那么 1 - 2 - 3 就等同于 (1 - 2) - 3 并且结果是 -4. 另外一方面,"="是右联的,所以 $a = $b = $c 等同于 $

PHP运算符优先级

在我们前面讲PHP逻辑运算符的时候,提到了PHP运算符的优先级,所谓的运算符优先级,指的是在表达式中哪一个运算符先计算,哪一个后计算,就好像,表达式 1 + 5 * 3 的结果 是 16 而不是 18 是因为乘号("*")的优先级比加号("+")高.如果有需要的话,可以用括号来强制改变优先级.例如:(1 + 5) * 3 的值为 18. PHP的运算符在运算中遵循的规则是:优先级高的操作先执行,优先级低的操作后执行,如果同一优先级,则按照从左到右的顺序进行,例如,&

PHP 运算符优先级介绍

运算符优先级指定了两个表达式绑定得有多“紧密”.例如,表达式 1 + 5 * 3 的结果是 16 而不是 18 是因为乘号(“*”)的优先级比加号(“+”)高.必要时可以用括号来强制改变优先级.例如:(1 + 5) * 3 的值为 18.如果运算符优先级相同,则使用从左到右的左联顺序. 下表从高到低列出了运算符的优先级.同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序. 运算符优先级 结合方向 运算符 附加信息 非结合 clone new clone 和 new 左 [ array

13 三元运算符 及 运算符优先级

1,基本语法: 条件表达式 ? 表达式1 : 表达式2: 2,表达式1和表达式2要为可以赋给接收变量的类型(或可以自动转换),否则会有精度损失 3,三元运算符可以转成 if-else 语句 4,运算符优先级 ①结合的方向只有三个是从右向左,其余都是从左到右 ②所有的双目运算符中只有赋值运算符的结合方向是从右向左 ③另外两个从右向左的结合运算符,一个是单目运算,还有一个是三目运算 ④逗号的运算符优先级最低 ⑤大概顺序 算术运算符 > 关系运算符 > 逻辑运算符 (逻辑非 ! 除外 )  >

C语言运算符优先级及结合性

今天去翻了下C语言运算符的优先级和结合性,发现当初学习的时候就没认真记住,惭愧.发现一篇讲得不错的文章,编辑了下转来供以后翻阅. C语言运算符优先级表(由上至下,优先级依次递减) 运算符 结合性 () [] -> . 自左向右 ! ~ ++ -- - (type) * & sizeof 自右向左 * / % 自左向右 + - 自左向右 << >> 自左向右 < <= > >= 自左向右 == != 自左向右 & 自左向右 ^ 自左向右

C运算符优先级和结合性

C中运算符优先级和结合性一览表: 在上表中能总结出一下规律: (1)结合方向只有三个是从右往左,其余都是从左往右: (2)逗号运算符的优先级最低: (3)对于优先级,有一个普遍规律:算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符,逻辑运算符中的“!”除外. 下图是一些容易出错的优先级问题: 原文地址:https://www.cnblogs.com/Cqlismy/p/11773674.html