运算符与函数行为

Operator vs functions behaviour

本文关键字:函数 运算符      更新时间:2023-10-16

我正在阅读以下文档,

https://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers

并发现下面的陈述有点模棱两可:

与C++不同,new 是一个函数,而不是运算符;new int 是一个语法错误。

在C++中,我们将运算符实现为函数,例如 +使用operator+ .

那么,一般来说,编程语言中运算符函数的确切区别是什么?

函数和运算符之间的实际区别取决于编程语言。在普通 C 中,运算符是语言本身的一部分。不能添加运算符,也不能更改现有运算符的行为。C++的情况并非如此,在中,运算符被解析为函数。

从完全不同的角度来看,考虑 Haskell,其中任何(二进制(函数都可以被视为二元运算符:

如果你不会说 Haskell,但知道点积,这个例子应该仍然相当简单。鉴于:

dotP :: (Double, Double) -> (Double, Double) -> Double
dotP (x1, y1) (x2, y2) = x1 * x2 + y1 * y2

dotP (1,2) (3,4)

(1,2) `dotP` (3,4)

会给11。

为了解决 Go 文档中的引用:Go 开发人员只是强调,在C++中,人们会把 new 视为具有自己语法的关键字,而 Go 中的 new 应该像任何其他函数一样对待。

尽管我仍然认为这个问题基本上是C++中运算符和函数之间的差异的重复?,但可能值得澄清这种差异在您引用的特定上下文中意味着什么。

重点是,C++中的函数是具有名称和可能的函数参数的东西,并且使用以下语法进行调用:

func(arg1,arg2,...)
换句话说,首先是名称,然后

是圆括号,然后是逗号分隔的参数列表。这是C++的函数调用语法。

运算符以标准第 5 条所述的方式使用。语法的细节因运算符的类型而异,例如有一元运算符如&,二元运算符如+*等;还有三元条件运算符? :,然后还有特殊的关键字,如newdeletesizeof,其中一些转换为用户定义类型的函数调用,但它们不使用上面描述的函数调用语法。即你不打电话

new(arg1,arg2,...)

但是,你使用了一个特殊的"一元表达式语法"(§5.3(,这意味着,除其他外,关键字new后面没有圆括号(至少,不一定(。

作者在您引用的部分中谈到的正是这种语法差异。

"运算符和函数有什么区别?"语法。 但事实上,这纯粹是一个关于语言:在C++中,+是一个中缀运算符(并且仅运算符可以是中缀(,func()将是一个函数。 但即使这并不总是正确的:MyClass::operator+()一个函数,但它可以,并且通常使用运算符语法。

其他语言有不同的规则:在像Lisp这样的语言中,没有真正的区别。 人们可以区分内置函数与用户定义函数,但区分有点人为,因为您可以轻松地扩展 Lisp 以添加其他内置函数。 还有允许对用户定义的中缀表示法使用中缀表示法的语言功能。 像Python这样的语言在它们之间映射:lhs + rhs映射到函数调用lhs.__add__( rhs )(所以"运算符"实际上只是句法糖(。

我总结说,一般来说,编程语言没有规则。只有两个不同的单词,每种语言都是可以随意使用它们,以最好地描述语言。

那么,一般来说,编程语言中运算符与函数的确切区别是什么?

它是广泛的。在抽象语法树中,运算符是一元、二进制或有时是三元节点 - 将表达式绑定在一起,具有一定的优先级,例如 +的优先级低于*,而的优先级又低于new

函数是一个更抽象的概念。作为基元,它们是类型化的子例程入口点,根据语言的不同,这些入口点可以用作具有词法作用域的右值。

C++允许通过动态调度运算符评估到所述方法,用方法覆盖(重载(运算符。这是一个语言"功能",正如这个问题的存在所暗示的那样,它主要使人们感到困惑,并且在 Go 中不可用。

运算符是 C++ 语言语法的一部分,在C++中如果你不想要默认行为,你可以将它们"重载"为函数,对于复杂类型或用户定义的类型,语言可能没有已知的运算符的语义,所以 yuser 可以用自己的实现重载它们。