关于++/--优先级的问题

xdl1990323 2015-04-25 07:51:24
x初值为5,那么对于x-=x-x--,x的自减操作到底是什么时候进行?是在x=5-(5-5);完成后再自减?
...全文
218 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-04-27
  • 打赏
  • 举报
回复
赵4老师 2015-04-27
  • 打赏
  • 举报
回复
不要写连自己也预测不了结果的代码! 自己写代码搞不清楚算符优先级请多加括号。 看别人代码搞不清楚算符优先级能调试的话请单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话想办法照写一小段孤立的可调试的代码然后单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话且没有办法照写一小段孤立的可调试的代码然后单步调试对应汇编的话只能参考算符优先级表猜了(提醒:并不能100%猜对)。
//C++ Operators
//  Operators specify an evaluation to be performed on one of the following:
//    One operand (unary operator)
//    Two operands (binary operator)
//    Three operands (ternary operator)
//  The C++ language includes all C operators and adds several new operators.
//  Table 1.1 lists the operators available in Microsoft C++.
//  Operators follow a strict precedence which defines the evaluation order of
//expressions containing these operators.  Operators associate with either the
//expression on their left or the expression on their right;    this is called
//“associativity.” Operators in the same group have equal precedence and are
//evaluated left to right in an expression unless explicitly forced by a pair of
//parentheses, ( ).
//  Table 1.1 shows the precedence and associativity of C++ operators
//  (from highest to lowest precedence).
//
//Table 1.1   C++ Operator Precedence and Associativity
// The highest precedence level is at the top of the table.
//+------------------+-----------------------------------------+---------------+
//| Operator         | Name or Meaning                         | Associativity |
//+------------------+-----------------------------------------+---------------+
//| ::               | Scope resolution                        | None          |
//| ::               | Global                                  | None          |
//| [ ]              | Array subscript                         | Left to right |
//| ( )              | Function call                           | Left to right |
//| ( )              | Conversion                              | None          |
//| .                | Member selection (object)               | Left to right |
//| ->               | Member selection (pointer)              | Left to right |
//| ++               | Postfix increment                       | None          |
//| --               | Postfix decrement                       | None          |
//| new              | Allocate object                         | None          |
//| delete           | Deallocate object                       | None          |
//| delete[ ]        | Deallocate object                       | None          |
//| ++               | Prefix increment                        | None          |
//| --               | Prefix decrement                        | None          |
//| *                | Dereference                             | None          |
//| &                | Address-of                              | None          |
//| +                | Unary plus                              | None          |
//| -                | Arithmetic negation (unary)             | None          |
//| !                | Logical NOT                             | None          |
//| ~                | Bitwise complement                      | None          |
//| sizeof           | Size of object                          | None          |
//| sizeof ( )       | Size of type                            | None          |
//| typeid( )        | type name                               | None          |
//| (type)           | Type cast (conversion)                  | Right to left |
//| const_cast       | Type cast (conversion)                  | None          |
//| dynamic_cast     | Type cast (conversion)                  | None          |
//| reinterpret_cast | Type cast (conversion)                  | None          |
//| static_cast      | Type cast (conversion)                  | None          |
//| .*               | Apply pointer to class member (objects) | Left to right |
//| ->*              | Dereference pointer to class member     | Left to right |
//| *                | Multiplication                          | Left to right |
//| /                | Division                                | Left to right |
//| %                | Remainder (modulus)                     | Left to right |
//| +                | Addition                                | Left to right |
//| -                | Subtraction                             | Left to right |
//| <<               | Left shift                              | Left to right |
//| >>               | Right shift                             | Left to right |
//| <                | Less than                               | Left to right |
//| >                | Greater than                            | Left to right |
//| <=               | Less than or equal to                   | Left to right |
//| >=               | Greater than or equal to                | Left to right |
//| ==               | Equality                                | Left to right |
//| !=               | Inequality                              | Left to right |
//| &                | Bitwise AND                             | Left to right |
//| ^                | Bitwise exclusive OR                    | Left to right |
//| |                | Bitwise OR                              | Left to right |
//| &&               | Logical AND                             | Left to right |
//| ||               | Logical OR                              | Left to right |
//| e1?e2:e3         | Conditional                             | Right to left |
//| =                | Assignment                              | Right to left |
//| *=               | Multiplication assignment               | Right to left |
//| /=               | Division assignment                     | Right to left |
//| %=               | Modulus assignment                      | Right to left |
//| +=               | Addition assignment                     | Right to left |
//| -=               | Subtraction assignment                  | Right to left |
//| <<=              | Left-shift assignment                   | Right to left |
//| >>=              | Right-shift assignment                  | Right to left |
//| &=               | Bitwise AND assignment                  | Right to left |
//| |=               | Bitwise inclusive OR assignment         | Right to left |
//| ^=               | Bitwise exclusive OR assignment         | Right to left |
//| ,                | Comma                                   | Left to right |
//+------------------+-----------------------------------------+---------------+
dbzhang800 2015-04-27
  • 打赏
  • 举报
回复
嗯,理论上,编译器可以将这种未定义行为的代码解释成关机、磁盘格式化等等。
lin5161678 2015-04-27
  • 打赏
  • 举报
回复
引用 8 楼 xdl1990323 的回复:
引用 6 楼 booirror 的回复:
这种不确定的代码,你不要这么写不就完了。纠结这个究竟有多少意义
就是感觉很好奇,为啥c不制定一套完整的准确的规范,把这种权利下放到编译器,真是奇怪了
不是这种权利下放到编译器 根本没下放 标准只是不要求编译器对这种特殊情况进行处理罢了 特意处理 会增加编译器实现的难度 而且收益低 因为这种表达式完全不应该出现
一根烂笔头 2015-04-27
  • 打赏
  • 举报
回复
--属于后缀表达式,- 属于additive表达式,后缀表达式要比- 先运算,-=属于赋值,优先级较低。 如果不理解可以这样假设:假设先-那么得到的结果是个lvalue对其--操作,对C语言来说是不成立的 可以使用x -= (x - x)--;验证
fanlvlgh 2015-04-26
  • 打赏
  • 举报
回复
这种问题真没探讨的必要,绝大部分情况下,没有使用价值
booirror 2015-04-25
  • 打赏
  • 举报
回复
这种不确定的代码,你不要这么写不就完了。纠结这个究竟有多少意义
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
再附上 x += x += x+ --x; 003917A5 mov eax,dword ptr [x] 003917A8 sub eax,1 003917AB mov dword ptr [x],eax 003917AE mov ecx,dword ptr [x] 003917B1 add ecx,dword ptr [x] 003917B4 add ecx,dword ptr [x] 003917B7 mov dword ptr [x],ecx 003917BA mov edx,dword ptr [x] 003917BD add edx,dword ptr [x] 003917C0 mov dword ptr [x],edx 可见自增和自减 在作为前缀或后缀时还是有很大的不一样
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
附上vs2010下反汇编的结果 x += x += x+x--; 009617A5 mov eax,dword ptr [x] 009617A8 add eax,dword ptr [x] 009617AB add eax,dword ptr [x] 009617AE mov dword ptr [x],eax 009617B1 mov ecx,dword ptr [x] 009617B4 add ecx,dword ptr [x] 009617B7 mov dword ptr [x],ecx 009617BA mov edx,dword ptr [x] 009617BD sub edx,1 009617C0 mov dword ptr [x],edx
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
引用 2 楼 fly_dragon_fly 的回复:
一个表达式对同一变量两次副作用的结果看编译器人品
这。。。。在DEV c++上最后进行x的自减
fly_dragon_fly 2015-04-25
  • 打赏
  • 举报
回复
一个表达式对同一变量两次副作用的结果看编译器人品
window_W 2015-04-25
  • 打赏
  • 举报
回复
加个括号好像就可以了吧
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
x--的返回值是5没错,但问题是表达式x-=x-x--需要对x值进行改写,而x--也要对x改写,那么谁先谁后
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
引用 7 楼 yangyunzhao 的回复:
都说了行为未定义,天知道是什么结果,换个编译器,或者换件衣服,结果都可能不一样
恩 确实
xdl1990323 2015-04-25
  • 打赏
  • 举报
回复
引用 6 楼 booirror 的回复:
这种不确定的代码,你不要这么写不就完了。纠结这个究竟有多少意义
就是感觉很好奇,为啥c不制定一套完整的准确的规范,把这种权利下放到编译器,真是奇怪了
yangyunzhao 2015-04-25
  • 打赏
  • 举报
回复
都说了行为未定义,天知道是什么结果,换个编译器,或者换件衣服,结果都可能不一样

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧