在这种情况下,为什么输出不是4?

时间:2015-07-28 07:02:43

标签: c

#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p;
    p += 2;
    printf("%d", *p);
    return 0;
}

前缀++的优先级大于解除引用,因此,p现在应该指向第二个元素。因此,当我们向其添加2时,它应指向第4个元素,答案应为4。但是,答案是3,为什么呢?

8 个答案:

答案 0 :(得分:7)

在像++*p这样的表达式中,优先级根本不起任何作用。在此表达式中,内部运算符适用于p(在这种情况下为*)。外部运算符(++)适用于内部运算符的结果。

如果您更换它们以获取*++p,则++将适用于p,而*将适用于++p的结果。< / p>

每当你有一堆unary / postfix操作符在操作数的同一侧上时,它们就会以内向外的顺序应用。

对于右侧示例,p++[i]运算符++适用于p[i]适用于p++的结果。同时,p[i]++运算符[i]适用于p,而++适用于p[i]的结果。

优先权开始在“含糊不清”的案件中发挥作用,如:

  • 一元/后缀运算符与二元运算符,例如

    *p + 2
    

    在上述情况下,一元*的优先级高于二元+,从而产生(*p) + 2

    p->i / 5
    

    此处,postfix ->的优先级高于二进制/,从而产生(p->i) / 5

    一般来说,一元/后缀运算符的优先级高于二元运算符。

  • 一元与后缀运算符,即操作数的两个侧的运算符,例如

    *p++
    

    在上述情况下,后缀++的优先级高于一元*,导致*(p++)

    &p->i
    

    此处postfix ->的优先级高于一元&,导致&(p->i)

    一般来说,后缀运算符的优先级高于一元运算符。

  • 各种更具“异国情调”的案例,如?:运营商......

答案 1 :(得分:2)

表达式++*p中的优先级没有问题,因为没有歧义可以解决。运算符从操作数向外应用。也就是说,首先应用*p,并将++应用于该表达式的结果。该语言不允许一个操作员在另一个操作员面前跳过。

在两个运算符都可以应用于同一操作数的情况下,优先级规则很重要,例如

*p++

在您的示例中并非如此。

关于结果,增量不会影响parr仍会指向p += 2;的第一个元素,直到您使用p递增它为止。这使得arr[2]指向3,其值为three.js

答案 2 :(得分:2)

arr[0]开始指向第一个元素++

在前缀 - p操作中,*p指向(arr[0]arr[0])的元素会递增,p现在包含2而不是1.指针本身不会改变。

p(指针,而不是它指向的元素)然后递增2,因此arr[2]指向table_default_styles ...其值为...... 3。

答案 3 :(得分:2)

因为第一个操作首先取消引用然后递增一个。 另一个操作将索引从0增加到2

如果输出arr[0],则会看到该值已递增。

请参阅precendence of the operator ++(前缀)和*(取消引用)。 它们具有相同的优先权并且位于同一个单元格中。关于 从右到左的关联性。它们的评估如下:

++(*p)
  

位于同一单元格中的运算符(可能有多行   在单元格中列出的运算符使用相同的优先级进行评估   给定的方向。例如,表达式a = b = c被解析为   a =(b = c),而不是(a = b)= c,因为从右到左的相关性。

工作示例:

#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p; 
    p += 2;
    printf("%d", *p);
    printf("%d", arr[0]);
    return 0;
}

输出:

32

http://ideone.com/6Xlt5N

答案 4 :(得分:1)

让我回答一下:

++*p

首先取消引用然后递增值

*++p

递增指针地址,然后取消引用。

答案 5 :(得分:1)

如果您将程序更改为更详细的模式:

functions.php

您将获得以下输出:

#include <stdio.h>

int main()
    {
      int arr[] = {1, 2, 3, 4, 5};
      int *p = arr;
      printf("\n1- %p",p);
      ++*p;
      printf("\n2- %d",arr[0]);
      printf("\n3- %p",p);
      p += 2;
      printf("\n4- %p",p);
      printf("\n5- %d", *p);
      return 0;
    }

答案 6 :(得分:1)

当两个operatos可以关联到同一个操作数时,Precednce解析操作顺序。例如,在2*x+7中,*优先于+的优先级将计算顺序解析为加法前的乘法:(2*x)+7

在您的情况下,只有一个运算符适用于p,它是一个解除引用运算符:*p。预增量运算符处理解除引用的l值:++(*p)因此优先级在此处无关。

答案 7 :(得分:1)

关于您的问题,代码++*p的值为*p+1,而不是address指向的p。正确的代码是++p。我希望这可以帮到你。