关于 &(x++) 不是左值的疑问。

diyer2002 2010-04-20 08:52:02
下面一段程序。
	int x = 0, *p;
p = &(++x); //正确
// p = &(x++); 错误,不是左值


这里x++,和++x的区别在哪呢?括号起了什么作用?
...全文
962 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
lizzoe 2010-04-20
  • 打赏
  • 举报
回复
简单一点,左值就是可以被赋值的东东,不能被赋值的就是右值。

左值,顾名思义,是出现在赋值符号左边的东西。

x++先返回一个对象引用,然后再++对象本身。
++x,先加加,再返回对象本身。
飞天御剑流 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 guzhijie1981 的回复:]
绝对没有误导
16 int a[10];
17 a++;
这个代码错误信息如下
../src/CTest.c:17: error: invalid lvalue in increment
这个可是号称最符合标准的gcc编译结果哦
[/Quote]

invalid lvalue在这里的意思,并不是说a不是左值。增量运算符要求操作数是可修改的左值,但表达式中的数组名(除作为&、sizeof及字符串字面量的初始化器等几种情况外),会根据数组到指针的隐式转换规则由一个左值转换为一个右值指针,因此才会出现invalid lvalue in increment的错误,并非说明数组名是一个右值。
飞天御剑流 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 myth_cn 的回复:]
引用 6 楼 supermegaboy 的回复:

引用楼主 diyer2002 的回复:
下面一段程序。

C/C++ code
int x = 0, *p;
p = &(++x); //正确
// p = &(x++); 错误,不是左值



这里x++,和++x的区别在哪呢?括号起了什么作用?


这个问题C与C+……
[/Quote]

不是这种原因,纯粹规定而已。
wisact 2010-04-20
  • 打赏
  • 举报
回复
学到了。。。。。。。。。
superhard_d 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 zhangweiit 的回复:]
如果你去看一下c++的操作符重载,就会发现前++与后++的区别了
前++,会返回x的引用,是一个左值,
而后++会产生临时变量,不能当左值用
[/Quote]
樱木同学开始好好学习了
zhangweiit 2010-04-20
  • 打赏
  • 举报
回复
如果你去看一下c++的操作符重载,就会发现前++与后++的区别了
前++,会返回x的引用,是一个左值,
而后++会产生临时变量,不能当左值用
diyer2002 2010-04-20
  • 打赏
  • 举报
回复
我试了一下,果然在C下都通不过,“完全求值”和 "左值转换"这俩概念能再详细解释一下吗?

[Quote=引用 6 楼 supermegaboy 的回复:]

引用楼主 diyer2002 的回复:
下面一段程序。

C/C++ code
int x = 0, *p;
p = &(++x); //正确
// p = &(x++); 错误,不是左值



这里x++,和++x的区别在哪呢?括号起了什么作用?


这个问题C与C++是不同的。

在C里,表达式被完全求值,本质就是进行最后的左值转……
[/Quote]
Myth_cn 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 supermegaboy 的回复:]

引用楼主 diyer2002 的回复:
下面一段程序。

C/C++ code
int x = 0, *p;
p = &(++x); //正确
// p = &(x++); 错误,不是左值



这里x++,和++x的区别在哪呢?括号起了什么作用?


这个问题C与C++是不同的。

在C里,表达式被完全求值,本质就是进行最后的左值转……
[/Quote]
补充一下:
为什么在C++里面 ++x被规定为左值而x++被规定为右值呢?
因为++x直接在x存储的地方将x+1后直接返回x,没有临时变量的拷贝操作,
而x++是先将x拷贝入临时变量,然后返回的是临时变量,再然后将x+1。
记得C++Primer里面有的
guzhijie1981 2010-04-20
  • 打赏
  • 举报
回复
绝对没有误导
16 int a[10];
17 a++;
这个代码错误信息如下
../src/CTest.c:17: error: invalid lvalue in increment
这个可是号称最符合标准的gcc编译结果哦
不知名小ITer 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 guzhijie1981 的回复:]

x++ 应该是先使用了临时变量;而临时变量可能在寄存器,所以是不允许取&的;也就是所谓的不是左值得;
比如数组名字;就不是左值。
凡是你觉得没有内存地址存放的都是左值;因为这些临时变量可能存放在寄存器;所以无法赋值
[/Quote]
小新...你又误导别人了...数组名字,就不是左值--这显然是错的嘛...数组名是左值,但是是个不可修改的左值.正是因为数组名,C语言里才会有可修改的左值和不可修改的左值的说法.
飞天御剑流 2010-04-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 diyer2002 的回复:]
下面一段程序。

C/C++ code
int x = 0, *p;
p = &(++x); //正确
// p = &(x++); 错误,不是左值



这里x++,和++x的区别在哪呢?括号起了什么作用?
[/Quote]

这个问题C与C++是不同的。

在C里,表达式被完全求值,本质就是进行最后的左值转换,而C中的&运算符对操作数的要求是左值或者函数,无论++x还是x++的结果都是右值,因此在C里无论&(x++)还是&(++x)都是非法的;

但在C++里,表达式不被要求进行完全求值,最后的左值转换是否进行视乎标准的规定以及环境需求,环境需求指的是只在要求右值的时候才进行左值转换。在C++里,前增量表达式的结果被规定为左值,因此&(++x)合法,但后增量的结果是右值,因此&(x++)非法。
guzhijie1981 2010-04-20
  • 打赏
  • 举报
回复
x++ 应该是先使用了临时变量;而临时变量可能在寄存器,所以是不允许取&的;也就是所谓的不是左值得;
比如数组名字;就不是左值。
凡是你觉得没有内存地址存放的都是左值;因为这些临时变量可能存放在寄存器;所以无法赋值
debugger2008 2010-04-20
  • 打赏
  • 举报
回复
应该是先算括号里面的吧?
[Quote=引用 1 楼 xiuxianshen 的回复:]
编译器问题,一个是++后赋值,一个是赋值后++
你这里的&(++x)等于&(x);x++;
而&(x++)等x++;&(x);
[/Quote]
dns007 2010-04-20
  • 打赏
  • 举报
回复
mark too!
pengzhixi 2010-04-20
  • 打赏
  • 举报
回复
p = &(x++);//因为x++返回的是一个临时变量,这个临时变量保存的是增加前的x值。而临时变量的生存期是很短的,是不能作为左值的也不能对它进行取址运算。
xiuxianshen 2010-04-20
  • 打赏
  • 举报
回复
编译器问题,一个是++后赋值,一个是赋值后++
你这里的&(++x)等于&(x);x++;
而&(x++)等x++;&(x);
东大坡居士 2010-04-20
  • 打赏
  • 举报
回复
我说用GCC编译咋两个都提示错误呢~~~`
赵4老师 2010-04-20
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编不就啥都明白了吗。

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧