C中算术指针后增量输出的说明

时间:2018-03-26 04:39:28

标签: c pointers dereference operator-precedence post-increment

void x(){

     int x[] = {9, 8, 7, 6, 5, 4, 3, 2, 1}; 
     int *p = x + 1;

         while (*p++ >5)
         printf ("%d ", *p); 
         printf ("\n");

}

输出:{7,6,5}

考虑到C中的优先级和结合性,我想仔细检查我的理由背后的原因是什么。

调用该函数时,它会自上而下执行,不带参数。

首先,我们有一个包含9个元素的数组x。

第二,我们有一个指针p,它指向元素x [1];

第三,我们跳进while循环,每次* p ++>都是如此。 5。 这里首先评估的是增加p ++的地址,所以对于第一个元素x [1],我们有一个大于5的值8,所以p递增(p ++ = x [2] = 7)x [2] = 7成为新的* p值(因为它现在指向x [2])并且打印了7。

接下来我们有7大于5,p递增(p ++ = x [3] = 6)所以6打印然后我们有6仍然大于5,p递增(p ++ = x [ 4] = 5)所以打印5,到目前为止我们已经打印了{7,6,5}。

然后我们评估x [4]的位置,它是5,不大于5,所以我们跳出while循环,最后输出。 {7,6,5}。

我对这个问题的推理是否正确?

5 个答案:

答案 0 :(得分:3)

您可以想象while语句

while (*p++ >5)

以下方式

while ( 1 )
{
    int *tmp = p;
    ++p;
    int value = *tmp;

    if ( !( value > 5 ) ) break; 
    //...
}

正如您所看到的,阵列的任何元素都没有改变。

最初p指向x[1]。因此x[1]的值与5进行比较,而指针p本身在循环体内向右移动一个位置,它指向x[2]x[2]的值输出{1}}。等等。

考虑到postincrement运算符具有比解除引用运算符更高的priotity,并且postincrement运算符的值是在递增之前其操作数的值。

还要考虑这个简单的示范程序。

#include <stdio.h>

int main(void) 
{
    int a[] = { 1, 2 };
    int *p = a;

    printf( "%d\n", *p++ );
    printf( "%d\n", *p );

    return 0;
}

它的输出是

1
2

答案 1 :(得分:3)

  

我对这个问题的推理是否正确?

自行

 while (*p++ >5)
     printf ("%d ", *p);

以更简单的形式等同于

 while (*p >5)
 {
     p = p + 1;           // Or: p++; Or: ++p;
     printf ("%d ", *p);

 }

然后是的,你的推理是正确的

如果您处于初级水平,我建议您避免在复杂表达式中使用预增量(++x)和后增量(x++)。它们是许多初学者错误的原因。仅将它们用作单个表达式。保持简单,避免许多错误。

答案 2 :(得分:1)

后缀增量/减量具有高优先级,但操作数的实际增量或减量被延迟(在语句完成执行之前的某个时间完成)。所以在声明中y = x * z ++; z的当前值用于计算表达式(即,z ++计算为z),z仅在完成所有其他操作后递增

答案 3 :(得分:0)

  

我对这个问题的推理是否正确?

是的,除了第3步。

while (*p++ >5)

*p++ > 5检索p的值:第一次指向x[1]或8. p的原始值用于取消引用并获取int 8. 85进行比较。

在上述某个时间,p会增加 - 在下一个序列点之前。除了用于取消引用的值之外,C没有指定何时发生的是指针p的原始值。

答案 4 :(得分:-3)

* p ++ - &gt; post increament / pre increament运算符具有高于解除引用运算符的优先级。第一指针p递增。如果它是预增量运算符,则p递增到下一个地址,然后指针被解除引用。但是在后增量的情况下,指针增量将被推迟,直到指针p上的未决操作完成,即解除引用操作。  你的理解是正确的。