为啥 ++(*p) 没有给出 l-value required 错误?
Posted
技术标签:
【中文标题】为啥 ++(*p) 没有给出 l-value required 错误?【英文标题】: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,为什么编译器不报错?
【问题讨论】:
【参考方案1】:
*p
将是常量值 [...]
不,和arr[0]
一样。
所以
++(*p);
和
一样++(p[0]);
和
一样++(arr[0]);
这是一个完全有效的陈述。
【讨论】:
【参考方案2】:对象指针取消引用本身不会产生指针指向的值。相反,它会生成一个引用该值的左值。用标准的话来说:
一元
*
运算符表示间接。如果操作数指向一个 函数,结果是一个函数指示符;如果它指向一个 对象,结果是一个指定对象的左值。如果操作数 类型为“类型指针”,结果类型为“类型”。
(C2011,6.5.3.2/4;强调)
一元*
因此是一类可以被认为对对象的身份进行操作的运算符,而不是对其值进行操作。 &
运算符和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 同意了。纠正了。以上是关于为啥 ++(*p) 没有给出 l-value required 错误?的主要内容,如果未能解决你的问题,请参考以下文章
move semantic/ r-value /L-value (copy from stakcoverflow)
C语言错误:left operand must be l-value