C语言中 int a=5,b=-3,c=4;printf("%d %d",(++a,b++,b++),b++);为什么结果是-2 -2?

int a=5,b=-3,c=4;printf("%d %d",(++a,b++),b++);为什么结果就变成-3 -3?

首先我们看逗号表达式:
格式:表达式1,表达式2,...表达式n;

它的原理是这样的,执行表达式1,再执行表达式2,一次类推。。。一直执行到表达式n;
但是最后整条语句的最终结果取表达式n的值;
比如,有一个这样的语句:a = (1,2,3);那a的值最终结果为3;

因此(++a,b++,b++)此表达式的最终取值,从形式上看是取决于表达式3的b++(还有其他细节,后面讲);

所以我们把printf("%d %d",(++a,b++,b++),b++);这条语句化简为:
printf("%d %d", b++, b++);

再来看++的运算符,当它被加在变量前表示,“变量先计算后使用”,加在变量后表示“变量先使用后计算”;

所以再次将以上语句printf("%d %d", b++, b++);化简为:
printf("%d %d", b, b);

可是这样看来好像最后输出结果应该是-3,而不是-2,是怎么回事呢?别急,还有一个细节要讲:
其实在逗号表达式的运算过程中,无论表达式是什么形式,它都会展开进行运算完毕后在进入下一个表达式进行运算。是什么意思呢?举一个例子吧:
比如表达式是这样的:(a = 1, a++ , a),这个表达式,展开后是这样的(a = 1,a = a + 1,a),它从左往右执行的时候,其实a的值已经在第二个表达式进行运算过,并且值已经重新存储过了此时a的值变成了2。因此,在第三个表达式的时候,其实a的值已经变成了2;

回到原题,在这条语句printf("%d %d",(++a,b++,b++),b++)的逗号表达式(++a,b++,b++)中,在第二个表达式运算时,其实已经将b值改变了,此时b已经变成了-2,而我们的化简printf("%d %d", b++, b++);中又由于 受到++运算“变量先使用后计算”的原则,因此会先将-2输出到屏幕中(虽然b的最终存储的值为-1);

同理,可以推得
int a=5,b=-3,c=4;
printf("%d %d",(++a,b++),b++);
它的等效程序化简过程如下:
(++a,b++),它的最终结果去看它的第二个表达式 b++; ++a,可以去除,
因此得到:
printf("%d %d", b++, b++);
在根据“先使用后计算的原则”再化简为:
printf("%d %d", b, b);
b = b+1;
b = b+1;
因此虽然b的值最终存放为-1,但是在打印输出的值为-3,-3;

我再补充一点,关于你的这道题不存在printf这个函数是从左往右还是从右往左算的问题,这道题无论是从哪里开始计算,结果都是一样的。
假如题目改成这样:
printf("%d %d",(++a,b++,++b),b);
如果是从左往右算,那输出结果是 -1, -1;
如果是从右往左算,那输出结果是 -3, -1;
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-03-03
#include <stdio.h>
int main(void)
{
    int a=5,b=-3;
    
    printf("%d %d",(++a,b++),b++);
    
    return 0;
}
 
//gcc编译结果
gcc -Wall -ansi -S -o m.s main.c 
main.c: 在函数‘main’中:
main.c:9: 警告:‘b’上的运算结果可能是未定义的

andl $-16, %esp
subl $32, %esp
movl $5, 24(%esp) //a = 5
movl $-3, 28(%esp) //b = -3
movl 28(%esp), %ecx //printf最右边参数 b = -3
addl $1, 28(%esp) //b ++ b = -2
addl $1, 24(%esp) //a ++ a = 6
movl 28(%esp), %edx //printf倒数第二个参数 b = -2
addl $1, 28(%esp) //b++
movl $.LC0, %eax //准备printf参数%d %d
movl %ecx, 8(%esp) //以下是参数入栈
movl %edx, 4(%esp)//就是将ecx eax edx的值压栈
movl %eax, (%esp)
call printf //调用printf
//最后结果是 -2 -3
//不同的编译器处理是不一样的,不要写这种代码
//如果是考试题目,参考往年的题目跟着答案写,死记硬背

本回答被提问者采纳
第2个回答  2014-03-03
经过试验那个括号起一个运算符的作用
作用:
d=(++a,b++,b++)
d代表的是最后一个内容块,即b++,括号内前两个进行先运算得出相应的结果追问

printf("%d %d",(++a,b++,b++),b++);
中,对输出的计算是从右到左求值的,那么输出应该是-2 -3啊

追答

(++a,b++,b++)代表的是最后一个内容块,即b++
括号内前两个进行先运算得出相应的结果
也就是说你那句相当于
++a;
b++;
printf("%d%d",b++,b++);

追问

先看这个
void main()
{
int a=1,b=2,c=3;
printf("%d %d %d",b,a+++b++,++b+c);
}
结果是3 4 6 所以是从右向左算的

追答

抱歉,能力有限

第3个回答  2014-03-03
(++a,b++)这里面是逗号表达式,也就是说只是输出b++这个表达式,由于是后缀因此输出的当然是-3追问

printf("%d %d",(++a,b++,b++),b++);
为什么是-2 -2? 谢谢你的回答,没有财富值了,不然就给你了

第4个回答  2014-03-03
这水平先学易语言吧