user-0 提问: 关于序列点问题求解答

回复:
user: user-0
content: 引用 17 楼 sholber 的回复:讨论得很热烈啊，大神真多啊。在下有一事不明：  Va++(0)先计算，之后是V||判断左边表达式为0，无法得出结果，这时左边表达式结束，||序列点作用出现所以执行Sa++（1）。之后就是判断b++的运算结果为0，得出V||（0），最后对c赋值，完成b++（1），“;”结束。 以上是我的理解不知道对不对，有不对的地方请大家指出。

user: user-0
content: 引用 11 楼 zhao4zhong1 的回复:关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775非常感谢您的回答 对我很有用。

user: user-1
content: 讨论得很热烈啊，大神真多啊。在下有一事不明：

user: user-2
content: 引用 14 楼 zhourqaiai 的回复:非常感谢大家的回答，是不是因为运算符 &&、||、?: 和逗号运算符的第一个运算对象计算之后才会体现”||“的序列点作用。所以在语句：（a++）||（b++）；中，运算顺序是先算a=0，之后“||”体现序列点作用，清算左边a++的值为1，但是在清算之前已经判定a=0作为“||”的运算对象了，是吧？我这样理解有问题吗。 @paschen 。  你要这么说也不错， xxx  ||  yyy 是先计算 xxx表达式得到的结果，如果不能得到答案，再计算yyy表达式的结果 正如你s = a++ 其中a=0，那么s也等于0，同理，xxx的结果也将是0

user: user-3
content: 这句话相当于c=a||b+1;a=a+1

user: user-3
content: 引用 8 楼 MJ1314666的回复:这句话相当于c=a||b+1;a=a+1 擦，不好意思看错了。 这句话相当于 c=a||b; a=a+1; b=b+1;

user: user-0
content: @paschen

user: user-0
content: 非常感谢大家的回答，是不是因为运算符 &&、||、?: 和逗号运算符的第一个运算对象计算之后才会体现”||“的序列点作用。所以在语句：（a++）||（b++）；中，运算顺序是先算a=0，之后“||”体现序列点作用，清算左边a++的值为1，但是在清算之前已经判定a=0作为“||”的运算对象了，是吧？我这样理解有问题吗。 @paschen 。

user: user-4
content: #include<stdio.h> int main(void) { int a = 0, b = 0, c, tmp_a, tmp_b; tmp_a=a++; tmp_b=b++; c=(tmp_a)||(tmp_b); printf("%d\t%d\t%d", a, b, c); } 程序理解成这样你就懂了，无论是a++还是++a，都会用一个临时变量来存放结果值的，用a++或者++a来运算都是用临时变量来运算的

user: user-2
content: 关键是你的副作用并没有不影响c的结果，a++中的++确实应该是发生在计算b++之前，但是是在 得到  || 第一个表达式结果之后  可参看：《裘宗燕：C/C++ 语言中的表达式求值》这篇文章

user: user-5
content: 关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

user: user-0
content: &&和||也会产生序列点， 因为","会产生序列点，所以"||"左边的表达式必须先求值，如果有副作用，副作用也会生效。然后才会继续处理","右边的表达式。 表达式a++就有副作用，它返回a当前的值后，要对a进行加1的操作。 按上面所说a++的副作用是对a加1，那么在a++后出现的“；“就意味着a+1的操作完成比如： a = 3； c=（a++） + 3； // 在这一步”；“出现之前a=3，”；“出现后表示a=4，但是给c赋值时用的a依旧是3，这个我是很明白。c=6。. ...... 那么上文中所说的”；“的序列点作用如果是这样的话，”||”难道不是标识着其左边的a++自加的结束吗。如果不是那么a++要什么时候自加？不用给我说a++和++a的区别了，我知道的，我只是想知道我对序列点的理解是不是有问题，错在哪里了。而不是单纯的对或者错，我想知道为什么。大白话解释，谢谢。

user: user-1
content: int i = 0; int f (void)  {     i ++;      return 0; }  int g (void) {     return i ++ + f (); }

user: user-6
content: 引用 5 楼 paschen 的回复:“左边的a++自加完毕才会进行或运算” 完全错误！ 除非你写成++a才是你描述这样  你这个根顺序点也没有半毛钱关系，如果你表达式改为：c=(a++)||(a++); 那么由于顺序点的原因，表达式的结果是不确定的  但你这个表达式和这些都没任何关系，不要想多了，把基础知识打好

user: user-2
content: “左边的a++自加完毕才会进行或运算” 完全错误！ 除非你写成++a才是你描述这样  你这个根顺序点也没有半毛钱关系，如果你表达式改为：c=(a++)||(a++); 那么由于顺序点的原因，表达式的结果是不确定的  但你这个表达式和这些都没任何关系，不要想多了，把基础知识打好

user: user-0
content: 可能我的表述不是很清晰，是这样的，前置和后置++我完全可以理解，主要看了一些资料，如下： 序列点是程序执行序列中一些特殊的点。 当有序列点存在时，序列点前面的表达式必须求值完毕，并且副作用也已经发生， 才会计算序列点后面的表达式和其副作用。  什么是副作用？举例子来说明。  int a = 5; int b = a ++; 在给b赋值的语句中，表达式a++就有副作用，它返回a当前的值5后，要对a进行加1的操作。  哪些符号会生成序列点呢？  ","会生成序列点。 ","用于把多条语句拼接成一条语句。 例如：  int b = 5; ++ b; 可由","拼接成  int b = 5, ++b; 因为","会产生序列点，所以","左边的表达式必须先求值，如果有副作用，副作用也会生效。然后才会继续处理","右边的表达式。  &&和||会产生序列点 逻辑与 && 和逻辑或 || 会产生序列点。  因为&&支持短路操作，必须先将&&左边的表达式计算完毕，如果结果为false，则不必再计算&&右边的表达式，直接返回false。  ||和&&类似。 就是这样，我理解的是如果||有序列点作用的话， ||左边的a++自加完毕才会进行或运算，这样c应该等于1不是吗？如果我的理解有误的话，请指正，谢谢。

user: user-7
content: 引用 2 楼 paschen 的回复:和||没什么关系，楼主的问题是没分清后置++  a++的结果是0（a变成了1，但a++的结果是0），同理b，所以c是0+1

user: user-2
content: 和||没什么关系，楼主的问题是没分清后置++  a++的结果是0（a变成了1，但a++的结果是0），同理b，所以c是0

user: user-6
content: c=(a++)||(b++);表达式中a++的值为0，b++也是0，此时c的值为0，而执行完后a的值才是1，b的值此时也是1 a++是先执行表达式后再自增，执行表达式时使用的是a的原值。 ++a是先自增再执行表达示，执行表达式时使用的是自增后的a。