我试图理解括号如何影响表达式中的优先级:
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++)
并非如此?
答案 0 :(得分:7)
首先评估b++
。 b++
递增b
并在增量发生之前返回之前的值b
,。 b++
的结果和之后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++)
不起作用,因为您在评估后增加(后缀增量)。