2014-09-25 89 views
0

我想了解括号影响表达式中的优先级:为什么表达式*(b ++)不首先评估b ++?

int arr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
auto b = arr; 
std::cout << *(++b) << std::endl; 

// output : 1 

在这段代码中,我得到预期的输出,但如果我将其更改为:

std::cout << *(b++) << std::endl; 
// output 0 

我得到0作为输出。由于括号,我会先评估b++,然后再进行解引用。看来我错了,于是我完全删除了括号,并用*++b*b++进行了测试,并得到了相同的结果。这意味着括号不会影响这种表达式的优先级吗?为什么这是两个表达式的结果是equivelant:

*(b + 1) 
*(++b) 

但它不是与*(b++)的情况?

+6

因为这几乎是后缀增量的*定义*请解释你认为它应该做什么以及与前缀增量('++ b')有什么不同。 – delnan 2014-09-25 10:39:36

+0

tl; dr'b ++ == b',圆括号不会奇迹般地改变评估结果。 – user657267 2014-09-25 10:41:47

+0

@delnan是啊我意识到不同之处,但那是我关心的括号。 – 2014-09-25 10:43:56

回答

7

确实首先评估b++b++增量b并返回前面的b,之前增量发生了。之后的b++b的值的结果是不同的。把它看成是(使用int,而不是int *因为引用到指针使得签名丑):(除使用增加值before the next sequence point是不确定的行为)

int postfix_increment(int &x) { 
    int result = x; 
    x = x + 1; 
    return result; 
} 

如果引入作为括号结果的临时变量,为了确保首先评估它,可能更容易发现差异:

int *tmp = b++; 
// At this point, b == tmp + 1! 
std::cout << *tmp << std::endl; 
+0

okey它说得很清楚。顺便说一句,我猜你在tmp中缺少'*' – 2014-09-25 10:50:02

+0

@ Selman22是的,错过了'b'是一个指针,而不是int。幸运的是,解释完全没有区别。 – delnan 2014-09-25 10:51:35

0

*(b+1)工作,因为你做数学。数学考虑括号。只有在数学完成后,表达式才会被评估。

​​因为您在评估之前递增(前缀增量)。

*(b++)不起作用,因为您在评估后增加(后缀增量)。

1

*(b++)相当于存储旧指针,递增指针和解除引用旧指针

int* post_increment(int* b) 
{ 
    int* old = b; 
    ++b; 
    return old; 
} 

它是一种有益的练习写围绕一个普通的指针的薄迭代包装。在编写用户定义的迭代器时,通常会将上面的post_increment()函数编写为过载的operator++(int)int的论点纯粹是为了区分它与预增加运算符operator++()。另外,您需要重载operator*()来取消引用迭代器。

相关问题