
c语言的问题 a = (++a)+(++a)+(++a)+(++a) 计算原理
#include<stdio.h>intmain(void){inta=1;printf("%d\n",(++a)+(++a));a=1;printf("%d\n",(+...
#include <stdio.h>
int main(void)
{
int a = 1;
printf("%d\n",(++a)+(++a));
a = 1;
printf("%d\n",(++a)+(++a)+(++a);
a = 1;
printf("%d\n",(++a)+(++a)+(++a)+(++a));
a = 1;
printf("%d\n",((++a)+(++a))+((++a)+(++a)));
a = 1;
printf("%d\n",(++a)+(++a)*(++a)+(++a)); /* 应该理解是4+4*4+5 */
a = 1;
printf("%d\n",(++a)+(++a)*(++a)*(++a)); /* 应该理解是5+4*4*5 */
return 0;
}
gcc下输出为:
6
10
15
16
25
85
==========================
网上有人说这种计算没有意义,和vc下输出结果是不相同的。
只是想知道,这样计算的原理是什么?
比如第一个我的理解是2+3=5,可结果是6;
第二个,我的理解是 2+3+4=9,可结果为10;
还有最后一个,如果勉强的理解为两数加的时候要统一加1,那三个数相乘的时候,为什么前两个不变,最后一个数加1了? 展开
int main(void)
{
int a = 1;
printf("%d\n",(++a)+(++a));
a = 1;
printf("%d\n",(++a)+(++a)+(++a);
a = 1;
printf("%d\n",(++a)+(++a)+(++a)+(++a));
a = 1;
printf("%d\n",((++a)+(++a))+((++a)+(++a)));
a = 1;
printf("%d\n",(++a)+(++a)*(++a)+(++a)); /* 应该理解是4+4*4+5 */
a = 1;
printf("%d\n",(++a)+(++a)*(++a)*(++a)); /* 应该理解是5+4*4*5 */
return 0;
}
gcc下输出为:
6
10
15
16
25
85
==========================
网上有人说这种计算没有意义,和vc下输出结果是不相同的。
只是想知道,这样计算的原理是什么?
比如第一个我的理解是2+3=5,可结果是6;
第二个,我的理解是 2+3+4=9,可结果为10;
还有最后一个,如果勉强的理解为两数加的时候要统一加1,那三个数相乘的时候,为什么前两个不变,最后一个数加1了? 展开
3个回答
2013-11-16
展开全部
gcc的做法是这样的:
数学运算符是左结合的,所以数学算式是从左到右进行扫描的
如果要进行一个二元运算,要先把它的两个操作数准备好。
++a是左值,它的值是累加了1之后的a,是【变量】。而a++则仅仅是一个【值】,这个值等于变量a的原始值。
因此对于(++a)+(++a)+(++a),过程如下:
先取第一个++a和第二个++a,以进行二元运算“+”
此时,经过两次++,a的值变为3
因此计算结果为a+a=6,此时不再是变量,而是值6
然后再取第三个(++a)
a的值变为4
因此最终结果为6+a=10
同理
(++a)+(++a)*(++a)*(++a)
第一步是处理+两边的操作数,取第一个++a,此时a变为2
之后开始从+后面确定第二个操作数
但此时扫描到了第一个*,因为优先级比+高,所以转入处理(++a)*(++a)
因此此时a变为4,结果为a*a=16
之后再处理第四个(++a),a变为5,16*a=80
完成高优先级的乘法之后,退回到加法的处理
a+80=85
当然,就结果而言,这些都是无意义的。
且不说不同的环境处理可能不同,表达式本身的意义也很模糊
因此实际使用中一定要避免这种一眼看不清会发生什么事的表达式
追问
对于(++a)+(++a)+(++a)+(++a),a初始值为1,
按照c语言的优先级,先算括号里的,那么第一个括号到第四个括号分别赋值为
a=2;a=3;a=4;a=5;
a应该只有一个内存空间,这样要是按照优先级走的话,会不知直接导致前面的a=2会被后面的a=5覆盖掉,然后再按照加法的左到右的结合性运算?
如果不这样,怎么理解c语言中,括号的优先级比加法的优先级要高?
追答
不,优先级并不一定是指哪打哪,而gcc目前的机制可以描述为是扫到哪是哪。在这一过程中用到类似递归的概念:如果后面的优先级更高,先处理后面的,完成后再处理当前的。
比如
2*3+7*6*(8+9)
那么这个表达式是被这样处理的:
先扫到2*3+
因为+的等级低,所以不管,算出6
然后6+7*
因为*的等级高,所以先把6+放在一边
7*6*,算出42
42*(
因为(的等级高,所以先把42*放在一边
8+9,算出17
然后遇到),返回到42*
算出714
然后遇到表达式结尾,返回到6+
算出720
整个过程就是这样
可以看到,这个过程并不是扫描整个算式,先捡优先级高的去处理,只是运算符毗邻时按高低序处理而已。
当然,不同的编译器可能会有不同的处理方式,但是核心思想都比较接近了。
更详细的原理可以参考“编译原理”方面的书。
展开全部
从右往左编译,从左往右输出。
3+3
4+3+3
5+4+3+3
(5+5)+(3+3)
后面的就不知道了。
应该是
5+4*4+4
5+5*4*4
3+3
4+3+3
5+4+3+3
(5+5)+(3+3)
后面的就不知道了。
应该是
5+4*4+4
5+5*4*4
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
第一个:后面的++a运行完了前后都是3,结果是3+3=6
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询