无法理解,如何评估以下陈述:
++*++ptr and *ptr++++
根据我的理解,首先会给我lValue,因为在应用*之后它会给出不能用于++运算符的值。但是,结果却相反。请解释一下。
第二个语句给出错误:batch3.c:6:21:错误:需要左值作为递增操作数 printf("%d",* ptr ++++);
答案 0 :(得分:2)
首先,一些standardese:
6.5.2.4后缀增量和减量运算符
约束
1后缀增量或减量运算符的操作数应具有原子的,合格的, 或不合格的真实或指针类型,并且应该是可修改的左值。
语义
2后缀++
运算符的结果是操作数的值。作为副作用, 操作数对象的值递增(即,相应类型的值为1 添加到它)。 参见附加算子的讨论和复合赋值 有关约束,类型和转换以及操作对其影响的信息 指针。结果的值计算在副作用之前排序 更新操作数的存储值。关于不确定的顺序 函数调用,postfix++
的操作是单个评估。对象上的Postfix++
with atomic type是一个带有memory_order_seq_cst
的读 - 修改 - 写操作 记忆顺序语义。 98)
...
6.5.16分配操作员
...
3赋值运算符将值存储在左操作数指定的对象中。一个 赋值表达式具有赋值后的左操作数的值, 111) 但不是 左值。赋值表达式的类型是左操作数将具有的类型 在左值转换后。更新左操作数的存储值的副作用是 在左右操作数的值计算之后排序。评估 操作数没有排序。
强调我的。
该文本墙的结果是表达式ptr++
和++ptr
的结果不是左值。但是,两个表达式都会产生指针值,因此它们可能是一元*
运算符的操作数,*ptr++
和*++ptr
的结果可能是左值。
这就是++*++ptr
有效的原因;你正在递增*++ptr
的结果,这可能是一个左值。但是,*ptr++++
被解析为*(((ptr)++)++)
(后缀++
的优先级高于一元*
); ptr++
的结果是第二个++
的操作数,但由于ptr++
的结果不是左值,编译器会抱怨。如果您将其写为(*ptr++)++
,那么表达式将是有效的。
简而言之:
++*++ptr - valid, equivalent to ++(*ptr++)
*++++ptr - invalid, equivalent to *(++(++ptr)), result of ++ptr is not an lvalue
++++*ptr - invalid, equivalent to ++(++(*ptr)), result of ++*ptr is not an lvalue
*ptr++++ - invalid, equivalent to *((ptr++)++), result pf ptr++ is not an lvalue
(*ptr)++++ - invalid, equivalent to ((*ptr)++)++, result of (*ptr)++ is not an lvalue
(*ptr++)++ - valid
答案 1 :(得分:1)
++
运算符优先于*
因此指针将首先递增,然后解除引用。
*p++
首先
p++
然后*p++
对于++
,必须有一个需要递增的值。但是下面的表达式并没有为++
提供左值。 p++
不是可修改的左值。
*ptr++++;
答案 2 :(得分:1)
考虑到这两个表达式是分开的(注意and
已定义<iso646.h>
),这里会发生什么:
第一个++*++ptr
相当于++(*(++ptr))
,因为前缀++
和一元*
具有相同的precedence,并且从右到左的共生性为他们都。请参阅以下example作为说明:
#include <stdio.h>
int main(void)
{
int a[] = {1, 2};
int *ptr = a;
++(*(++ptr));
printf("%d\n", a[0]);
printf("%d\n", a[1]);
return 0;
}
结果:
1
3
后一个表达式不可编译,因为ptr++
子表达式不是可修改的左值。请注意,postix ++
具有更高的优先级,*
(间接运算符)及其关联性是从左到右。