问题 一元运算符是否合理是否有意义?


来自的C ++运算符优先级表 http://en.cppreference.com/w/cpp/language/operator_precedence (我知道它不是规范性的,但标准不讨论优先级或关联性)将一元运算符标记为右/左关联。

从对不同问题的讨论中,我有些疑惑。一元运算符是否合理是否有意义?


3348
2017-10-18 18:30


起源

看到我的回答(stackoverflow.com/a/14084830/1740808)以具有左关联前缀运算符的hyphotetical语言为例 - SergeyS


答案:


它只是从语法中得出关联性的方式的人工制品。

原因 添加是左关联的是其中一个产品 添加剂的表达 是 添加剂的表达 + 乘法表达,左边是加法表达式。所以当你看到:

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 ++ 是  一元运算符。它是一个后缀运算符。但这确实无关紧要,除非它是标准中的术语,因为很明显它是一个运算符,它有一个操作数,所以英语中的“一元”。


9
2017-10-18 20:39



请参阅我的答案(stackoverflow.com/a/14084830/1740808),其中包含左关联前缀运算符的hyphotetical语言示例 - SergeyS


在一元运算符的情况下,运算符的相关性仅确定运算符出现在操作数的哪一侧。


2
2017-10-18 18:32



++和 - 可以出现在双方...... - Luchian Grigore
@LuchianGrigore和他们是不同的运营商。 - Seth Carnegie
啊,是的,它们出现2次 - 前缀前缀。 - Luchian Grigore
所以,底线,他们是联想的,只是与其他人没有相同的意义? - Luchian Grigore
@LuchianGrigore是的,因为它们不能具有与二元运算符相同的歧义,但是你必须弄清楚一元运算符在两个可能的操作数之间应用的操作数。 - Seth Carnegie


不确定,但如果以下是有效的,是的。

++i--

但事实并非如此,并抛出错误

lvalue required as increment operand

一元运算符的所有行为只能用优先级来解释。


1
2017-10-18 18:31



不,优先级决定会导致错误。 - Seth Carnegie
不,postfix的优先级高于前缀。 - Seth Carnegie


请考虑以下代码

int *p;
*p++;

表达方式 *p++ 可以评估为 (*p)++ (递增p指向的对象)或 *(p++) (指向p指向的下一个对象)。

因为一元运算符是正确的关联表达式 *p++ 将被评估为 *(p++)。 (我在阅读时想出了这个 Kernighan和Ritchie。)

似乎优先级和关联性已经改变并且后缀 ++ 优先级高于解除引用优先级 * 运营商。

根据C11,上述表达式将被评估为 *(p++)

我希望这能更清楚地说明为什么一元运算符具有相关性。

谢谢 Lucian Grigore 指出这个。


1
2017-10-12 07:08



Postfix是从左到右的关联 - en.cppreference.com/w/cpp/language/operator_precedence,所以争论不会成立。此外,在这种情况下,评估顺序由优先级决定,因为后增量优先于解除引用。 - Luchian Grigore
感谢您的见解。 - Shekhar Bhandakkar