为什么表达式*(b ++)不首先评估b ++?

时间:2014-09-25 10:37:56

标签: c++ pointers operators operator-precedence

我试图理解括号如何影响表达式中的优先级:

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++进行测试并获得相同的结果。这意味着括号不会影响这种表达式的优先级吗?为什么这两个表达式的结果是等价的:

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

*(b++)并非如此?

3 个答案:

答案 0 :(得分:7)

首先评估b++b++递增b并在增量发生之前返回之前的bb++的结果和之后b的值不同。可以将其视为(使用int而不是int *,因为引用指针会使签名变得丑陋):

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

(除了使用递增的值before the next sequence point是未定义的行为。)

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

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

答案 1 :(得分:1)

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

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

在普通指针周围编写一个瘦的迭代器包装器是一项有益的练习。在编写用户定义的迭代器时,上面的post_increment()函数通常写成重载的operator++(int)int参数纯粹是为了将它与预增量运算符operator++()区分开来。此外,您需要重载operator*()来取消引用迭代器。

答案 2 :(得分:0)

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

*(++b)有效,因为您在评估之前递增(前缀增量)。

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