好吧,表示被C语言的表达式语句坑的跟狗一样,或者是因为C那种松散的语言特性。这种特性有时候能带来更大的编程自由度,有时让人很无奈 。
有这么一个表达式:int i = 7;printf("%d\n",i++*i++);这个printf语句输出的结果是什么?49,擦,为毛不是56?自增运算符++,他的作用是使表达式的值自增1,i++与++i的区别在于:i++是表达式的值是原来i的值,做完运算之后i的值加1,而++i的值为i的值加1,做完运算之后i的值加1。那这样的话,不管从哪个顺序算这个表达式的值,似乎应该是56才对。在吉林大学康辉老师的讲解中:编译器在对自增或者是自减的表达式求值时,编译器总是按照前缀先处理然后处理后缀,然后处理前,所有表达式i的初值都为最开始对i的赋值。按照这个说法,上面的printf语句输出的结果应该为49而不是56。这样,似乎这个问题就解决了。但是,只北的东西总要有点与众不同的。考虑一下这个表达式:int i = 3;printf("%d\n",i++*++i+i--*--i);按照上面的求解方式,嗯,先考虑++i,和--i,i初值都是3,那么++i=4,--i=2,i++=3,i--=3,那么表达式的值应该为:3*4+3*2=18,嗯,用vc6.0验证一下,结果如下:
这操蛋的结果,怎么是25了?!!!这不科学。好吧,翻了一下steve summit的《你必须知道的495个C语言问题》。其中是这么解释的:尽管后缀自增和后缀自减操作符在输出其旧值之后才会执行运算,但是这里的“之后”的含义和准确的定义常常被误解。无法保证自增或自减会在放弃变量原值之后和对表达式的其他部分进行计算之前立即进行,只能保证变量的更新会在表达式“完成”之前的某个时刻进行(按照ansi c术语,在下一个“序列点”(序列点:是一个时间点,所有的副作用都以确保结束)之前)。这种被称之为:“未定义”的。好吧,写到这里,我也不知道到底怎么才能有效且正确的算出类似于上面两个表达式的值。简单来说,这些表达式的值可能要依赖于编译器在进行自增或自减操作时的解释规则。在你完全弄清楚你的编译器是怎么解释这些表达式,或者是你要写一个具有较高可移植性的程序前,不要试图编写类似上面那样操蛋的表达式。