Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在条件评估中最终要进行后缀增量?_C++_C - Fatal编程技术网

C++ 为什么在条件评估中最终要进行后缀增量?

C++ 为什么在条件评估中最终要进行后缀增量?,c++,c,C++,C,GDB显示在整个评估=之后,obj->start_point增加 但是C Primer Plus告诉我++的优先级高于= 那么为什么obj->start\u point不首先递增呢?这本书错了吗 if (obj->start_point++ >= obj->data + obj->data_size) { 它确实具有更高的优先级。问题是variable++返回增量之前的值。如果要返回新值,必须在其前面加前缀:++variable 在您的情况下:如果(++obj->sta

GDB显示在整个评估
=
之后,
obj->start_point
增加

但是C Primer Plus告诉我
++
的优先级高于
=

那么为什么
obj->start\u point
不首先递增呢?这本书错了吗

if (obj->start_point++ >= obj->data + obj->data_size) {

它确实具有更高的优先级。问题是
variable++
返回增量之前的值。如果要返回新值,必须在其前面加前缀:
++variable

在您的情况下:
如果(++obj->start\u point>=obj->data+obj->data\u size){

执行
variable++
相当于调用此函数:

int increment_posfix(int *x)
{
    int temp = *x;
    *x = *x + 1;
    return temp;
}
执行
++变量时
相当于:

int increment_prefix(int *x)
{
    *x = *x + 1;
    return *x;
}
优先级仅控制运算符与操作数的分组,而不控制表达式的求值顺序

++
运算符的副作用不必在评估后立即应用,只需在下一个序列点之前应用

编辑

您当然可以查看生成的汇编代码,以了解编译器如何处理该特定情况,只需注意这取决于代码以及您如何编译它(不同的优化级别可能会影响它)

除了少数例外情况1,C不要求以任何特定顺序(从左到右、从右到左或任何其他顺序)计算表达式。在这种情况下,最重要的是我们将
obj->data+obj->data\u size
的结果与
obj->start\u point++
的结果进行比较。以下任何一种评估顺序都是可能的:

Order 1        
–––––––
tmp1 = obj->data + obj->data_size
result = obj->start_point >= tmp1
obj->start_point = obj->start_point + 1

Order 2
–––––––
tmp1 = obj->start_point
obj->start_point = obj->start_point + 1
tmp2 = obj->data + obj->data_size
result = tmp1 >= tmp2

Order 3
–––––—–
tmp1 = obj->start_point
tmp2 = obj->data + obj->data_size
obj->start_point = obj->start_point + 1
result = tmp1 >= tmp2
或者完全是别的什么

obj->start_point++
obj->data+obj->data_size
的求值甚至可以相互交错-毕竟,
obj->start_point
obj->data
obj->data_size
中的每一个都是需要求值的表达式

只要结果是正确的-我们将比较
obj->start_point
上后缀
++
操作符的结果与添加
obj->data
obj->data_size
的结果-编译器在如何排序每个子表达式的求值方面有很大的自由度,而这种排序不必进行修改在整个程序中保持一致(同一程序中其他地方的类似表达式的计算方式可能不同)

从评论中回答leoleohu的问题

莱奥廖胡问道 但我的问题仍然存在,谁决定postfix++在>=之后执行,prefix++在>=之前执行

这取决于编译器,对于同一代码中的每个表达式,它不必相同

前缀和后缀形式的
++
--
运算符都有结果和副作用

obj->start_point++
的结果是
obj->start_point
的当前值。副作用是在表达式中的
obj->start_point
中添加1

obj->start_point++ >= obj->data + obj->data_size
obj->start_point++
(当前值
obj->start_point
)的结果与
obj->data+obj->data_size
的结果进行比较

obj->start_point
中添加1的副作用可以发生在计算后的任何点上,只要它发生在下一个序列点之前。它可以在比较之前或之后应用-编译器可以根据当前优化级别、表达式中的其他操作数、周围的代码等


  • &&
    |
    ?:
    和逗号运算符(与函数调用中分隔参数的逗号不同)都强制从左向右求值。 当你问“为什么它不先增加?”,你必须非常小心你所问的。当你说
    obj->start\u point++
    时,至少会发生三件不同的事情:

  • 在某个时刻,我们将取
    obj->start\u point
    的旧值,并计算一个新值,
    obj->start\u point+1
  • 在某个时刻,我们将获取新值并将其存储回
    obj->start\u point
  • 我们将向外部表达式“返回”一些值。在这种情况下,我们将使用
    =
    运算符将“返回”的值与子表达式
    obj->data+obj->data\u size
    进行比较
  • 现在,我们可以确定的只有两种说法,我称之为“A”和“B”

    语句“A”——这是最重要的一条——是问题3的答案。对于
    ++
    的后缀形式,“返回”到外部表达式的值是旧值。这正是后缀
    ++
    操作的定义。这不是一个“操作顺序”问题,而是一个“接线员是干什么的?”他问道

    然后是语句“B”,它不那么有趣,而且非常明显,你甚至可能不会把它看作一个“东西”,它是,1必须在2之前发生——我们不能存储新的值,直到我们计算它之后

    但是,这也是非常重要的——这甚至值得贴上“语句C”的标签——认识到我们不能说其他任何东西。我们绝对不知道(在任何绝对意义上)当事情#1发生时。我们也不知道事情#2会发生。我们所知道的是事情#2会在事情#1之后发生,在整个表达式完成之前的某个时间(也就是正式地说,在下一个序列点之前)。(因此,我们可能有四件事可以说。)


    另请参见前面的问题,

    是的,这是后缀的全部要点,首先检查/读取变量,然后递增它。否则,请使用++obj->s