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

inta=5,b=-3,c=4;printf("%d%d",(++a,b++),b++);为什么结果就变成-3-3?... int a=5,b=-3,c=4;printf("%d %d",(++a,b++),b++);为什么结果就变成-3 -3? 展开
 我来答
leiwuyuan
2014-03-03 · TA获得超过207个赞
知道答主
回答量:85
采纳率:0%
帮助的人:86.9万
展开全部
首先我们看逗号表达式:
格式:表达式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;
wdwy003
2014-03-03 · TA获得超过2113个赞
知道小有建树答主
回答量:1073
采纳率:0%
帮助的人:1027万
展开全部
#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
//不同的编译器处理是不一样的,不要写这种代码
//如果是考试题目,参考往年的题目跟着答案写,死记硬背
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
禾土1126916513
2014-03-03 · TA获得超过100个赞
知道小有建树答主
回答量:98
采纳率:100%
帮助的人:81.3万
展开全部
经过试验那个括号起一个运算符的作用
作用:
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++);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
去吻你倔强的嘴
2014-03-03 · TA获得超过602个赞
知道小有建树答主
回答量:480
采纳率:0%
帮助的人:226万
展开全部
(++a,b++)这里面是逗号表达式,也就是说只是输出b++这个表达式,由于是后缀因此输出的当然是-3
追问
printf("%d %d",(++a,b++,b++),b++);
为什么是-2 -2? 谢谢你的回答,没有财富值了,不然就给你了
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2014-03-03
展开全部
这水平先学易语言吧
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(3)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式