【问题标题】:Why ++(*p) is not giving l-value required error?为什么 ++(*p) 没有给出 l-value required 错误?
【发布时间】:2017-09-16 05:21:20
【问题描述】:
#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p;
    p += 2;
    printf("%d", *p);
    return 0;
}

为什么这段代码没有给出任何编译时错误,我怀疑++*p 被评估为++(*p) 和*p 将是常量值1,当我们执行++(1) 这不是一个l-value,为什么编译器不报错?

【问题讨论】:

    标签: c arrays pointers lvalue


    【解决方案1】:

    *p 将是常量值 [...]

    不,和arr[0]一样。

    所以

    ++(*p);
    

    和

    一样
    ++(p[0]);
    

    和

    一样
    ++(arr[0]);
    

    这是一个完全有效的陈述。

    【讨论】:

      【解决方案2】:

      对象指针取消引用本身不会产生指针指向的值。相反,它会生成一个引用该值的左值。用标准的话来说:

      一元* 运算符表示间接。如果操作数指向一个 函数,结果是一个函数指示符;如果它指向一个 对象,结果是一个指定对象的左值。如果操作数 类型为“类型指针”,结果类型为“类型”。

      (C2011,6.5.3.2/4;强调)

      一元* 因此是一类可以被认为对对象的身份进行操作的运算符,而不是对其值进行操作。 &amp; 运算符和sizeof 运算符的某些用途也可以认为属于此类。

      【讨论】:

      • 是的。每个其他答案都忘记提及取消引用运算符的结果:)。
      【解决方案3】:

      *p 将是常量值

      不,不会。 *p 是 a[0] 当你做 int *p = arr; 时。 a[0] 不是常数值,由于它们相同,*p 也不是常数值。

      结果是这样的:

      ++(*p);
      

      相当于:

      ++(a[0]);
      

      它增加了数组第一个位置的元素,你可以清楚地看到。

      但是回头看++(*p),可以看到:

      • *p 取消引用指针,产生一个左值。
      • 然后我们有(*p),括号中的左值。
      • ++(*p) 将预增量运算符应用于左值,即值,因此不会产生编译器错误。

      【讨论】:

        【解决方案4】:

        为什么++(*p) 没有给出 l-value required 错误?

        指针上的取消引用运算符产生一个左值。 因此,*p 是一个左值,并且在其上使用预增量运算符是有效的。

        【讨论】:

          【解决方案5】:

          请注意您使用的两个语句:

          ++*p; // increments the value pointed by *p at that time `a[0]` by 1
          p += 2; // increments the address p is storing by 2
          

          并且没有 l-value required 错误的原因是因为在您的声明中:

          ++*p; // *p is not a constant, it is same as a[0]
          

          【讨论】:

          • "*p is not a constant, it points to a[0]" 不,*p 是 a[0]。
          • @alk ya,用词不当,词点在那里用词不当。会更新。谢谢:)
          • "its value is equal to a[0]" 这不仅仅是相等,甚至更多:它是相同的内存。
          • 可能是语言问题?在这种情况下,“相等”和“相同”是不一样的...... :-)
          • @alk 同意了。纠正了。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-07-02
          • 2013-04-03
          • 2013-12-10
          • 1970-01-01
          • 1970-01-01
          • 2010-10-25
          • 1970-01-01
          相关资源
          最近更新 更多