鱼C论坛

 找回密码
 立即注册
查看: 2733|回复: 20

[已解决]++运算符的运算逻辑是什么?

[复制链接]
发表于 2022-7-27 15:08:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这串代码的结果为什么会是14,x++不是应该是下一条语句才会加1吗?那这里的结果应该是13啊

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.   int x = 5, y;
  5.   y = 2 + (x += x++, x + 8, ++x);
  6.   printf("%d\n", y);
  7.   return 0;
  8. }
复制代码
最佳答案
2022-7-28 18:17:33
1613551 发表于 2022-7-28 14:18
懂了懂了,不过为什么这个是从右边先++x呢?我记得小甲鱼讲过,如果有逗号运算符是从左往右开始算的啊也 ...
  1. y = 2 + (x += x++, x + 8, ++x);
复制代码

1. 这个先计算 x += x++,得出一个未定义的结果
2. 然后计算  x + 8,这个表达式没有副作用,没有修改任何变量
3. 然后计算 ++x
4. 然后计算 y = 2 + (上一步++x的值)

第1步的结果未定义,就是不知道执行完x += x++后,x中保存的值是什么
第3步给 第1步得到的那个未定义的结果加1
如果第1步执行x += x++后得到的结果是1,那么这里 ++x后,x的值就变成了2
不要怀疑,既然是未定义的结果,为什么这个结果不能是1 ?
什么是未定义?
未定义就是标准没有规定这样的代码应该给出什么结果,交给编译器的设计者来决定
所以,如果第1步x += x++的结果是0,第3步执行完了结果就是1
如果第1步x += x++的结果是-1,第3步执行完了结果就是0
如果第1步x += x++的结果是64,第3步执行完了结果就是65
如果第1步x += x++的结果是520,第3步执行完了结果就是521
如果第1步x += x++的结果是250,第3步执行完了结果就是251
如果第1步x += x++的结果是1024,第3步执行完了结果就是1025
具体第1步会给出的结果是多少,这是真的不知道,不同的编译器很有可能给出不一样的结果,也可能给出一样的结果
就和下面这样的代码一样,你知道下面这个代码输出什么吗?不同的编译器很有可能不一样,当然也可以一样
  1. #include <stdio.h>

  2. int main(void) {
  3.     int x;
  4.     printf("%d\n", x);
  5.     return 0;
  6. }
复制代码


这就是代码的未定义行为,会得到什么结果都是可能的

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-27 15:23:48 | 显示全部楼层

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-27 15:25:21 | 显示全部楼层
本帖最后由 当初约定 于 2022-7-27 17:18 编辑

a=1;b=++a;b输出2,a输出2
a=1;b=a++;b输出1,a输出2
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 15:42:35 | 显示全部楼层
当初约定 发表于 2022-7-27 15:25
a=1;b=a++;b输出2,a输出2
a=1;b=++a;b输出1,a输出2

你这前++和后++反了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 16:36:41 | 显示全部楼层
Cocopeng 发表于 2022-7-27 15:42
你这前++和后++反了吧

+1
小甲鱼也是说++a是先加一再赋值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 16:42:52 | 显示全部楼层
是这样的,x+=x++应该是先算x=x+5,赋值为10,然后执行x++,x赋值为11,再然后计算最后一项++x,x先赋值12,再加到前面的2变为14
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 17:17:45 | 显示全部楼层
Cocopeng 发表于 2022-7-27 15:42
你这前++和后++反了吧

是反了,还是得靠实际上手的最具说服力,上手敲
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 17:49:00 | 显示全部楼层
寻章摘句老雕虫
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-27 19:53:46 | 显示全部楼层
不是在下一条语句之前加1
是在下一个顺序点之前加1
https://www.cnblogs.com/dolphin0 ... 6%22%E5%A4%84%29%3B

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-28 13:04:28 | 显示全部楼层
人造人 发表于 2022-7-27 19:53
不是在下一条语句之前加1
是在下一个顺序点之前加1
https://www.cnblogs.com/dolphin0520/archive/2011/0 ...

呀,我突然看不懂了,我看一楼的回答是,先从右边开始算,x先++,x=6,然后x=x+x++,等于12,然后加上前面的2,就是14了,没有把++算进来。

你的意思是这里有顺序点吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-28 13:05:02 | 显示全部楼层

我不是很理解,是要先从右边开始算的吗?逗号表达式不是从左边开始算吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-28 13:19:13 | 显示全部楼层
1613551 发表于 2022-7-28 13:04
呀,我突然看不懂了,我看一楼的回答是,先从右边开始算,x先++,x=6,然后x=x+x++,等于12,然后加上前面 ...
  1. x += x++
复制代码

这里没有顺序点
这个表达式有两个副作用
一个是 x += x
另一个是 x++
一个要把x的值修改成 x + x
另一个要把x的值修改成 x + 1

一个顺序点出现多个副作用的时候,标准没有定义哪个先哪个后
所以这个代码是未定义的,输出什么都是可以的


"""
如:

   x=x++;

   该表达式只有一个顺序点,在该顺序点之前有2个副作用,一个是自增,一个赋值,这两个副作用发生的顺序是未定义的,即自增运算和赋值运算哪一个先执行是没有被定义的(注意这个顺序跟运算符的优先级是无关的,注意理解运算符优先级的含义),这个执行次序交由编译器厂商去自行决定,因此对于不同的编译器可能会得出不同的结果。
"""
https://www.cnblogs.com/dolphin0 ... /04/20/2022330.html

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3 &amp;amp;#128002;

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-28 14:18:07 | 显示全部楼层
人造人 发表于 2022-7-28 13:19
这里没有顺序点
这个表达式有两个副作用
一个是 x += x

懂了懂了,不过为什么这个是从右边先++x呢?我记得小甲鱼讲过,如果有逗号运算符是从左往右开始算的啊也就是应该是x=x+x++,x+8,x++; 应该是先计算x+=x++

不要意思,学的又都还给小甲鱼了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-28 14:47:02 | 显示全部楼层
本帖最后由 1613551 于 2022-7-28 14:48 编辑
人造人 发表于 2022-7-28 13:19
这里没有顺序点
这个表达式有两个副作用
一个是 x += x


大佬你好,这第四条我还不是很理解
   
4)未重载的'&&'运算符的左操作数赋值之后(即"&&"处);
这句话我看不是很懂啊,然后有这样一串代码

  1. #include <stdio.h>
  2. int main(void)
  3. {
  4.   int x = -1, y = 4, k;
  5.   k = x++ <= 0 && !(y-- <= 0);
  6.   printf("%d,%d,%d\n", k, x, y);
  7.   return 0;
  8. }
复制代码

是不是碰到&&就算是到了顺序点,然后顺序点前面的副作用必须先算完
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-28 18:17:33 | 显示全部楼层    本楼为最佳答案   
1613551 发表于 2022-7-28 14:18
懂了懂了,不过为什么这个是从右边先++x呢?我记得小甲鱼讲过,如果有逗号运算符是从左往右开始算的啊也 ...
  1. y = 2 + (x += x++, x + 8, ++x);
复制代码

1. 这个先计算 x += x++,得出一个未定义的结果
2. 然后计算  x + 8,这个表达式没有副作用,没有修改任何变量
3. 然后计算 ++x
4. 然后计算 y = 2 + (上一步++x的值)

第1步的结果未定义,就是不知道执行完x += x++后,x中保存的值是什么
第3步给 第1步得到的那个未定义的结果加1
如果第1步执行x += x++后得到的结果是1,那么这里 ++x后,x的值就变成了2
不要怀疑,既然是未定义的结果,为什么这个结果不能是1 ?
什么是未定义?
未定义就是标准没有规定这样的代码应该给出什么结果,交给编译器的设计者来决定
所以,如果第1步x += x++的结果是0,第3步执行完了结果就是1
如果第1步x += x++的结果是-1,第3步执行完了结果就是0
如果第1步x += x++的结果是64,第3步执行完了结果就是65
如果第1步x += x++的结果是520,第3步执行完了结果就是521
如果第1步x += x++的结果是250,第3步执行完了结果就是251
如果第1步x += x++的结果是1024,第3步执行完了结果就是1025
具体第1步会给出的结果是多少,这是真的不知道,不同的编译器很有可能给出不一样的结果,也可能给出一样的结果
就和下面这样的代码一样,你知道下面这个代码输出什么吗?不同的编译器很有可能不一样,当然也可以一样
  1. #include <stdio.h>

  2. int main(void) {
  3.     int x;
  4.     printf("%d\n", x);
  5.     return 0;
  6. }
复制代码


这就是代码的未定义行为,会得到什么结果都是可能的

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-28 18:22:43 | 显示全部楼层
1613551 发表于 2022-7-28 14:47
大佬你好,这第四条我还不是很理解
   
4)未重载的'&&'运算符的左操作数赋值之后(即"&&"处);

是的,执行&&右边的!(y-- <= 0)之前,左边的x++ <= 0产生的副作用都已经完成

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-28 18:28:59 | 显示全部楼层
1613551 发表于 2022-7-28 14:47
大佬你好,这第四条我还不是很理解
   
4)未重载的'&&'运算符的左操作数赋值之后(即"&&"处);

这个程序y一定输出4,因为计算&&的右操作数之前,左操作数产生的副作用都已经完成

  1. #include <stdio.h>

  2. int main(void)
  3. {
  4.     int x = 3;
  5.     int y = 0;
  6.     int z = 0;
  7.     z = (y = x++ + 3) && (y = x);
  8.     printf("x=%d\n", x);
  9.     printf("y=%d\n", y);
  10.     printf("z=%d\n", z);
  11.     return 0;
  12. }
复制代码

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
1613551 + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-29 11:20:49 | 显示全部楼层
请结帖
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-29 14:10:05 | 显示全部楼层

不好意思,因为昨晚的我有点事,所以大家的回复还没来得及认真看,我现在就好好看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-29 14:18:30 | 显示全部楼层
人造人 发表于 2022-7-28 18:17
1. 这个先计算 x += x++,得出一个未定义的结果
2. 然后计算  x + 8,这个表达式没有副作用,没有修改 ...

谢谢大佬,我大致懂了,那也就是说以后写代码的过程中要尽量避免类似这样未定义的的行为
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 14:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表