来自的C ++运算符优先级表 http://en.cppreference.com/w/cpp/language/operator_precedence (我知道它不是规范性的,但标准不讨论优先级或关联性)将一元运算符标记为右/左关联。
从对不同问题的讨论中,我有些疑惑。一元运算符是否合理是否有意义?
来自的C ++运算符优先级表 http://en.cppreference.com/w/cpp/language/operator_precedence (我知道它不是规范性的,但标准不讨论优先级或关联性)将一元运算符标记为右/左关联。
从对不同问题的讨论中,我有些疑惑。一元运算符是否合理是否有意义?
它只是从语法中得出关联性的方式的人工制品。
该 原因 添加是左关联的是其中一个产品 添加剂的表达 是 添加剂的表达 + 乘法表达,左边是加法表达式。所以当你看到:
a + b + c
这必须相当于 (a + b) + c
,因为匹配生产的唯一方法是 a + b
作为 添加剂的表达 和 c
作为 乘法表达。 a
本身就是一个 添加剂的表达但是 b + c
不是一个 乘法表达 所以 a + b + c
如果我们试图采取与生产不匹配 a
作为 添加剂的表达。
如果你以前没有,我建议你阅读忽略语义的“表达式”章节:只查看语法产生。然后你会看到 怎么样 优先级和关联性是由语法定义的。最大的诀窍是每个“高优先级”类型的表达式IS-A“低优先级”类型的表达式。所以每一个 乘法表达 是一个 添加剂的表达但反之亦然,这就是使乘法“加强”而不是加法的原因。
前缀一元运算符在语法中定义如下: 一元表达式:++ 铸表达 依此类推,左侧为运算符,前缀为右侧,右侧为后缀。换句话说,我们在左边插入括号“forfix”,在右边插入前缀。也就是说,我们可以说,对于后缀运算符,分组是从左到右,对于前缀运算符,分组是从右到左。事实上,C ++标准正是如此(C ++ 03中的5.2 / 1和5.3 / 1)。可能是滥用术语或至少是一个新的造币来将这种一元分组称为“关联性”。但它并不是一个主要因素,因为它显然必须具有什么意义。
二进制和一元运算符之间的唯一区别是,如果二进制运算符按相反方向分组,则语法仍然有意义 a - b - c
手段 a - (b - c)
。这将是令人惊讶的,但不会影响语言。对于一元运算符来说,组合起来会更令人惊讶 !!a
如 (!!)a
,语言也必须提供 含义 对于子表达式 !!
,目前它没有。功能语言可以赋予它一个含义: !!
可能意味着由...组成的功能 !
和 !
,即与...相同的操作 static_cast<bool>()
但是C ++没有组合函数或运算符的概念。 C ++不需要提供这种含义的原因是 !
“从右到左”。哪个(因为语法中的大技巧)只是另一种说法 !!
不是语法正确的表达式,所以永远不是任何东西的子表达式。
是的,它 不 有意义地说,前缀运算符组从右到左,后缀运算符组从左到右。但是,由于我们了解C ++语言的其他事情,所以它必须是这样“显而易见”。
顺便说一句,我认为从技术上讲,至少在C ++中,postfix ++
是 不 一元运算符。它是一个后缀运算符。但这确实无关紧要,除非它是标准中的术语,因为很明显它是一个运算符,它有一个操作数,所以英语中的“一元”。
在一元运算符的情况下,运算符的相关性仅确定运算符出现在操作数的哪一侧。
不确定,但如果以下是有效的,是的。
++i--
但事实并非如此,并抛出错误
lvalue required as increment operand
一元运算符的所有行为只能用优先级来解释。
请考虑以下代码
int *p;
*p++;
表达方式 *p++
可以评估为 (*p)++
(递增p指向的对象)或 *(p++)
(指向p指向的下一个对象)。
因为一元运算符是正确的关联表达式 *p++
将被评估为 *(p++)
。 (我在阅读时想出了这个 Kernighan和Ritchie。)
似乎优先级和关联性已经改变并且后缀 ++
优先级高于解除引用优先级 *
运营商。
根据C11,上述表达式将被评估为 *(p++)
。
我希望这能更清楚地说明为什么一元运算符具有相关性。
谢谢 Lucian Grigore 指出这个。