关于c表达式++i++的问题。

「已注销」 2018-07-14 05:46:05
c code on freebsd.

#include <stdio.h>
int main(int argc, char* argv[]){
int i, j;
i = 5;
j = ++i++;
printf("%d\n", j);
return 0;
}

编译报错"expression is not assignable".
请问是何原因?谢谢
...全文
863 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-07-19
  • 打赏
  • 举报
回复
kang_bryant 2018-07-17
  • 打赏
  • 举报
回复
引用 7 楼 zangfong 的回复:
可以从i++和++i的实现来分析:
首先对于i++的实现是:

int temp;
temp = i;
i = i+1;
return temp;
i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对temp进行操作.(换句话说就是不能作为左值),因为temp是一个临时变量。

而++i的实现是:

i = i+1;
return i;
返回的就是变量i本身,所以没有问题。
回到
j = ++i++;
根据运算符++自右向左的结核性,上面的代码等同于
j = ++(i++);
则(i++)返回temp之后,不能作为左值,所以也就报错error: lvalue required as increment operand
反过来,如果改成
j = (++i)++;
就没有问题了。
分析的可以
FightingBoom 2018-07-17
  • 打赏
  • 举报
回复
引用 7 楼 zangfong 的回复:
可以从i++和++i的实现来分析:
首先对于i++的实现是:

int temp;
temp = i;
i = i+1;
return temp;
i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对temp进行操作.(换句话说就是不能作为左值),因为temp是一个临时变量。

而++i的实现是:

i = i+1;
return i;
返回的就是变量i本身,所以没有问题。
回到
j = ++i++;
根据运算符++自右向左的结核性,上面的代码等同于
j = ++(i++);
则(i++)返回temp之后,不能作为左值,所以也就报错error: lvalue required as increment operand
反过来,如果改成
j = (++i)++;
就没有问题了。

感觉解释的很对,赞一个
啊大1号 2018-07-17
  • 打赏
  • 举报
回复
https://blog.csdn.net/a3192048/article/details/81079262
「已注销」 2018-07-17
  • 打赏
  • 举报
回复
引用 17 楼 hemowolf 的回复:
[quote=引用 14 楼 qq_38319117 的回复:]
[quote=引用 13 楼 shiyanbo_1006 的回复:]
研究这问题?你确定工作中会用?
别把有限的时候浪费在无用的扯蛋上面了


假设,人家在工程中想精简代码,用一句代码写“i+1赋值给j,然后i++”的功能,应该写j=i+++1;结果有个大胆的想法写了j=++i++;发现报错,想知道为什么错了,难道是要加括号,然后来问问,你的工作是逛论坛吗,不然你在无用的扯蛋吗[/quote]

发现C/C++论坛里对这种问题讨论的热忱还是蛮高涨的,如果是在Java/C#组里这种写法早就被人怼回去了!在Java/C#里,这类写法除了用来装B没有任何作用,反而降低了程序的可读性。

不知道在C/C++里,这种代码的精简有多大现实性的意义,能给软件产品带来明显的性能提升吗?楼上大侠说的这个功能,非要写到一条语句里吗,如果写成两条语句就造成严重的后果吗?还是说,C/C++的软件工程师就是纯粹地为了追求代码上的美感?
[/quote]
我在研究编译原理。
大风起兮d 2018-07-17
  • 打赏
  • 举报
回复
j = ++i++;
这一句错误,++i++相当于++(i++),其中i++返回的是右值,相当于6,导致不能再自增了
会思考的草 2018-07-17
  • 打赏
  • 举报
回复
引用 14 楼 qq_38319117 的回复:
[quote=引用 13 楼 shiyanbo_1006 的回复:]
研究这问题?你确定工作中会用?
别把有限的时候浪费在无用的扯蛋上面了


假设,人家在工程中想精简代码,用一句代码写“i+1赋值给j,然后i++”的功能,应该写j=i+++1;结果有个大胆的想法写了j=++i++;发现报错,想知道为什么错了,难道是要加括号,然后来问问,你的工作是逛论坛吗,不然你在无用的扯蛋吗[/quote]
首先声明我这是休息时间,我自己的时间。
如果我们组有人在产品中写这样的代码,代码审核的时候我一定会要求改掉。而且组里的所有人都会如此做。
AlbertS 2018-07-16
  • 打赏
  • 举报
回复
需要左值吧,这样的问题适可而止吧,两个++还好,再多就不要管了,这个问题你可以一下什么叫左值和右值,然后就知道它为什么报错了
_肆 2018-07-16
  • 打赏
  • 举报
回复
引用 13 楼 shiyanbo_1006 的回复:
研究这问题?你确定工作中会用?
别把有限的时候浪费在无用的扯蛋上面了


假设,人家在工程中想精简代码,用一句代码写“i+1赋值给j,然后i++”的功能,应该写j=i+++1;结果有个大胆的想法写了j=++i++;发现报错,想知道为什么错了,难道是要加括号,然后来问问,你的工作是逛论坛吗,不然你在无用的扯蛋吗
待续_1006 2018-07-16
  • 打赏
  • 举报
回复
研究这问题?你确定工作中会用?
别把有限的时候浪费在无用的扯蛋上面了
卖水果的net 2018-07-16
  • 打赏
  • 举报
回复
j = ++i++;

++i ,这是一个表达式,而 n++ ,这里的n,应该是一个变量,或者一个属性。 表达式不行。

刚开始学习,不知道说的对不对。
cloudblaze 2018-07-16
  • 打赏
  • 举报
回复
这种代码只有大学考试中见到。
ShanTUT 2018-07-16
  • 打赏
  • 举报
回复
毛病出在“++i++ ”上面。
自增运算符(就是++)的结合性是从右至左,也就是说它是执行顺序是++(i++)。
自增运算符如果放在变量的右边,返回的是就是右值,右值是不可以改变的。
之后再做左边的自增运算时就会出错了。
小灰狼 2018-07-16
  • 打赏
  • 举报
回复
引用 14 楼 qq_38319117 的回复:
[quote=引用 13 楼 shiyanbo_1006 的回复:]
研究这问题?你确定工作中会用?
别把有限的时候浪费在无用的扯蛋上面了


假设,人家在工程中想精简代码,用一句代码写“i+1赋值给j,然后i++”的功能,应该写j=i+++1;结果有个大胆的想法写了j=++i++;发现报错,想知道为什么错了,难道是要加括号,然后来问问,你的工作是逛论坛吗,不然你在无用的扯蛋吗[/quote]

发现C/C++论坛里对这种问题讨论的热忱还是蛮高涨的,如果是在Java/C#组里这种写法早就被人怼回去了!在Java/C#里,这类写法除了用来装B没有任何作用,反而降低了程序的可读性。

不知道在C/C++里,这种代码的精简有多大现实性的意义,能给软件产品带来明显的性能提升吗?楼上大侠说的这个功能,非要写到一条语句里吗,如果写成两条语句就造成严重的后果吗?还是说,C/C++的软件工程师就是纯粹地为了追求代码上的美感?
芭蕉桑0_0 2018-07-16
  • 打赏
  • 举报
回复
我就看一看~~~
zangfong 2018-07-15
  • 打赏
  • 举报
回复
可以从i++和++i的实现来分析:
首先对于i++的实现是:

int temp;
temp = i;
i = i+1;
return temp;
i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对temp进行操作.(换句话说就是不能作为左值),因为temp是一个临时变量。

而++i的实现是:

i = i+1;
return i;
返回的就是变量i本身,所以没有问题。
回到
j = ++i++;
根据运算符++自右向左的结核性,上面的代码等同于
j = ++(i++);
则(i++)返回temp之后,不能作为左值,所以也就报错error: lvalue required as increment operand
反过来,如果改成
j = (++i)++;
就没有问题了。


「已注销」 2018-07-15
  • 打赏
  • 举报
回复
引用 8 楼 xaioxiaoguai 的回复:

我用的是freebsd操作系统
小小怪421 2018-07-15
  • 打赏
  • 举报
回复
跑不了的你 2018-07-15
  • 打赏
  • 举报
回复
引用 7 楼 zangfong 的回复:
可以从i++和++i的实现来分析:
首先对于i++的实现是:

int temp;
temp = i;
i = i+1;
return temp;
i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对temp进行操作.(换句话说就是不能作为左值),因为temp是一个临时变量。

而++i的实现是:

i = i+1;
return i;
返回的就是变量i本身,所以没有问题。
回到
j = ++i++;
根据运算符++自右向左的结核性,上面的代码等同于
j = ++(i++);
则(i++)返回temp之后,不能作为左值,所以也就报错error: lvalue required as increment operand
反过来,如果改成
j = (++i)++;
就没有问题了。

这个解答完整详细 赞!!!
void_ink 2018-07-14
  • 打赏
  • 举报
回复
加个括号就明白了: ++i++ 等同于 ++(i++),先计算括号,i++,得到的返回值是一个数值,再作 (++某数值),++操作符是对变量用的,对一个值操作当然不行
加载更多回复(5)

69,336

社区成员

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

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