圆括号用于分组被认为是一个运算符吗?

5
在 C 语言中,圆括号用于许多操作,如函数调用和类型转换。然而,它们也用于分组多个子表达式以改变运算符的顺序。我有一个疑问:当作为分组运算符使用时,它们是否被视为运算符?许多人说是,许多人说不是……

只有当 2(7) 可以得出 14 时,我才会回答是。否则,不是。 - Joe DF
@JoeDF 为什么?那完全不相关。我们这里不是在谈论乘法,而是括号。 - The Paramagnetic Croissant
我知道,但如果它们可以用于乘法,那么它们可以被视为运算符。显然,情况并非如此。 - Joe DF
它们无论如何都被视为运算符... :P - Joe DF
3个回答

3

6.5表达式章节(N1570)第3段

操作符和操作数的组合由语法指定。 85)

以下是注意事项:

85)语法指定了在表达式求值中运算符的优先级,其与此子句的主要子句的顺序相同,最高优先级最先。 因此,例如,二元+运算符(6.5.6)允许作为其操作数的表达式是在6.5.1到6.5.6中定义的那些表达式。 例外情况是强制类型转换表达式(6.5.4)作为一元运算符(6.5.3)的操作数,以及包含在任何以下运算符对之间的操作数:分组括号()(6.5.1),下标方括号[](6.5.2.1),函数调用括号()(6.5.2.2)和条件运算符?:(6.5.15)。

因此,C标准似乎将它们视为操作符。


2

括号不是一个真正的操作符,它们更像是元操作符——影响应用其他操作符的结果,而本身并不是操作符。同样地,花括号本身不是语句,但它们影响其他语句的组合。

将圆括号视为元操作符的一个原因是,在表达式被解析时,解析器生成的表达式树通常已经去除了分组括号*

*这并不意味着所有解析器都会删除括号——在某些情况下必须保留它们。例如,在代码格式化工具中,必须保留所有标记,包括注释和空格。然而,在解析表达式进行评估时,分组括号不会直接保留。


你的回答提出了一个有趣的观点,但标准似乎规定了另外一种方式。了解标准中运算符的定义将会很有意思... - xdevel2000
1
@xdevel2000 我相当确定这是C标准委员会措辞不当的结果。C++标准采用并扩展了C表达式,以不同的方式进行,将分组括号作为构造主要表达式的语法(第5.1.1.6节)。 - Sergey Kalinichenko

1

我相当确定,分组括号不应视为运算符。

请注意,脚注不是标准的一部分(即它们不具有规范性,换句话说,只提供信息)。

让我们先从运算符的定义开始(重点在此之后是我的):

C111 6.4.6 标点符号2

标点符号是具有独立的语法和语义意义的符号。根据上下文,它可以指定要执行的操作(进而可能产生值或函数标识符、产生副作用或两者兼而有之),这种情况下它被称为运算符(在某些上下文中还存在其他形式的运算符3)。操作数是运算符作用的实体。

接下来,让我们看一下括号表达式的定义:

C11 6.5.1/5 Primary expressions

括号表达式是一种基本表达式。它的类型和值与未加括号的表达式相同。如果未加括号的表达式分别是左值、函数指示器或空表达式,则括号表达式是左值、函数指示器或空表达式

空表达式不产生值或函数指示器。它的评估可能会产生副作用,但不必这样做,如以下示例所示:(void expr)

((void) 5); // here, no side effects are produced

在我看来,上述内容(通过反证法)证明了分组括号不是运算符。在这个上下文中,()只是用于表示带括号的表达式的终结符。请保留HTML标签。

1) 根据公开可用的N1570草案版本。

2) 相关引用基本与C90相同,尽管它位于6.1.5 运算符子句中,该子句已不再存在。

3) 这个短语是在C99中添加的。我认为它的目的是反映新的_Pragma运算符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接