为什么arr [-2]不等于-2 [arr]?

时间:2017-06-05 09:47:10

标签: c++ arrays undefined-behavior

#include <iostream>
using namespace std;

int main() 
{
    int arr[3] = { 10, 20, 30 };
    cout << arr[-2] << endl;
    cout << -2[arr] << endl;        
    return 0;
}

输出:

4196160
-30

此处arr[-2]超出范围且无效,导致未定义的行为。 但-2[arr]评估为-30。为什么呢?

arr[-2]不等同于-2[arr]吗?

4 个答案:

答案 0 :(得分:131)

-2[arr]被解析为-(2[arr])。在C(和C ++中,忽略重载),X[Y]的定义是*(X+Y)(请参阅this question中的更多讨论),这意味着2[arr]等于arr[2]

答案 1 :(得分:67)

编译器解析此表达式

-2

unary_minus decimal_integer_literal

这是整数文字的定义,不包括符号。

反过来表达

2[arr]

被编译器解析为后缀表达式。

Postfix表达式的优先级高于一元表达式。因此这个表达

-2[arr]

相当于

- ( 2[arr] )

因此,一元减号应用于后缀表达式2[arr]返回的左值。

另一方面,如果你写了

int n = -2;

然后

n[arr]

然后这个表达式等同于

arr[-2]

答案 2 :(得分:18)

if(is_admin() && !$order_id > 0 && isset($_GET['order_id'])) { $order_id = $_GET['order_id']; } 相当于-2[arr],相当于-(2[arr])。但是,-arr[2]相当于(-2)[arr]

这是因为Here is a working example to demonstrate. (JSFiddle)

答案 3 :(得分:2)

潜在问题在于运算符优先级。在C ++中,[],即下标运算符比- unary_minus运算符具有更多优先级(有点类似于preferance)。

所以当一个人写道时,

arr[-2]

编译器首先执行arr[]然后-,但是unary_minus被包含在[-2]的边界内,因此表达式被一起分解。

在,

-2[arr]

同样的事情发生但是,编译器首先在2[]运算符执行-因此它最终成为 -(2[arr])不是(-2)[arr]

您对这个概念的理解, arr[i] i[arr]*(i+arr)都是正确的。它们都是等价的表达式。

如果您想以这种方式书写,请将其写为(-2)[arr]。你肯定会得到相同的价值。

检查这一点以备将来参考:http://en.cppreference.com/w/cpp/language/operator_precedence