例如:
int x[100];
void *p;
x[0] = 0x12345678;
x[1] = 0xfacecafe;
x[3] = 0xdeadbeef;
p = x;
((int *) p) ++ ;
printf("The value = 0x%08x", *(int*)p);
编译上面的代码会在使用++运算符的行上生成一个左值所需的错误。
答案 0 :(得分:18)
强制转换创建一个int *
类型的临时指针。您不能增加临时值,因为它不表示存储结果的位置。
在C和C ++标准中,(int *)p
是右值,它大致意味着只能出现在赋值右侧的表达式。
p
是左值,这意味着它可以有效地出现在作业的左侧。只能增加左值。
答案 1 :(得分:3)
表达式((int *) p)
处理存储在变量p
中的指针是指向int的指针。如果要将变量本身视为指向int变量的指针(然后递增它),请使用引用强制转换:
((int *&) p) ++ ;
答案 2 :(得分:1)
您可以使用
获得预期的结果p = (int*)p + 1;
在取消引用指向p
的指针上使用增量运算符,这是一个左值,也有效:
(*(int**)&p)++;
但是,后者不可移植,因为(void*)p
可能与(int*)p
的表示形式不同。
答案 3 :(得分:1)
感谢larsmans指向正确的方向。
我冒昧地深入研究这个问题。因此,供将来参考,根据C99标准的第6.5.2.4和6.5.4节(http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf):
6.5.2.4后缀增量和减量运算符
约束
后缀增量的操作数 或减少运营商应具备的 合格或不合格的真实或 指针类型,应该是可修改的 左值
..
..
6.5.4铸造操作员
..
..
[脚注] 89)演员 不产生左值。因此,一个演员 到合格的类型有相同的 作为一个演员的效果不合格 该类型的版本。
注意:这仅适用于C. C ++可能以不同方式处理强制转换。
答案 4 :(得分:0)
Rvalue表达式((int *) p)
创建int*
类型的临时变量,但无法应用运算符++
。
++
需要左值作为其操作数。
由于@FredOverflow提及lvalues
而rvalues
与作业几乎没有关系。
数组是左值,但它们无法分配,因为它们是不可修改的。
std::string("Prasoon")
是一个右值表达式,它仍然可以出现在赋值运算符的左侧,因为我们被允许在临时值上调用成员函数(在这种情况下为operator =
)。