如果我们碰见了这么一个程序你能算出结果,并想明白吗?
1. k = i++ * ++j;
2. k = i++ + i++ i++;
3. k = ++i + ++i + ++i;
前置:++i,--i(先对变量的值进行加1或者减1,用处理后的结果来进行后续的运算过程)
后置:i++,i--(先用原值来进行后续的运算过程,等处理完之后,在对当前的这个值进行加1或者减1)
程序1:
#include <stdio.h> #include <conio.h> int main(){ int i,j,k; i = 3; j = 4; k = ++i * j++; printf("i is :%d\n,j is :%d\n,k is :%d", i, j ,k); getch(); return 0; }
(linux:)
对于这个为什么会变成这样,我们来看看(最好一步一步分析):
对于一个语句,有这么个规则,遇见一个运算符处理与否,完全取决于后面的运算符,比较两个运算符的优先级,若后者高,则不处理前者。
(k = ++i * j++)
有四个重要运算符:+, ++(前置)*, ++(后置),当然赋值运算符的优先级相对最低
首先取到的运算符是赋值,然后先不处理,取得下一个运算符,也就是前置(++),前置的优先级比赋值高,也就是暂时的忽略了第一个赋值运算符,但是此时后者(前置)能不能执行还取决于后面的运算符,可以看出,后面的是(乘,*),前置的优先级高于乘法(*),所以此刻,执行前置运算符
k = i * j++; (此时,k是垃圾值,i是4,j此刻也是4(当前语句还没处理完))
同样的:我们接着分析(遇见赋值,先不执行,下一个是乘法(*),考虑扔掉赋值,继续找下一个,后置,比较运算符的优先级,后置高于乘法(*),所以此刻执行的是后置运算符)
k = i * j;(此刻,k还是垃圾值,i是4,j也是4) 这里的这一条语句也就是后续运算(处理完后,k的值16),也就是说只有将其处理完,才会执行让j加1的命令,也就是下面的命令
j++;
对于后置,是先用原值参加完所有的后续运算,这里的这条语句就是后续运算,所以先用j=4参加完这条语句,然后j加1
此刻 i为4,j为5,k为16。
好了上面的解决了,我们再来看下面的:
程序二:
#include <stdio.h> #include <conio.h> int main(){ int i,k; i = 3; k = i++ + i++ + i++; printf("i is :%d\n,k is :%d", i, k); getch(); return 0; }
2.运行结果(Linux)
windows
这里可以将语句(k = i++ + i++ + i++)分解:
1. k = i + i++ + i++
2. k = i + i + i++
3. k = 2i + i 此刻i为3,k为9
i++
i++
i++所以我们的到的结果是:k为9,i为6
Linux
这里也可以将语句(k = i++ + i++ + i++)分解:
1. k = i + i++ + i++
i++;(第一个后置自增,此刻i为4)
2. k = i + i + i++ (即就是:k = 8 + i++)此刻i仍然为4,所以当运算进行到这里,k也就确定k=12
i++;(第二个后置自增)此时i为5
i++;(第三个后置自增)此时i为6
所以我们的到的结果是:k为12,i为6
大家可以看到,对于上面两者的不同,应该就是编译器对语句对自增运算符处理的结果不同吧!!!哈哈
简而言之:就是不同环境下的后续运算不一样
window(vc6.0):将整条语句都当作后续运算
linux,window(dev-c++):不以一整条语句为后续运算符,以每一天小的分语句作为标准
程序三:
#include <stdio.h> #include <conio.h> int main(){ int i,k; i = 3; k = ++i + ++i + ++i; printf("i is :%d\n,k is :%d", i, k); getch(); return 0; }
(Linux)
语句(k = ++i + ++i + ++i)也是后续运算,这里也将其分解后应该是这样:
1. k = i + ++i + ++i 此时i的值为 4
2. k = i + i + ++i 此时i的值为5
k = 10 + ++i
3. k = 10 + i 此时i的值为6
k的值为16,i的值为6