关于后缀++运算符

来源:互联网 发布:python getoptions 编辑:程序博客网 时间:2024/05/17 21:52

C语言的后缀++运算符一直都没能理解得很透彻过。

这次决心一定要把这个问题给弄清楚,理解个明明白白地,不然心里这个阴影影响我的HAPPY生活。

首先,按大部资料记载后缀++,意思是先取值后做运算。下面一段程序可以很好的表现其含义:

int main(){int i = 10;printf("i=%d", i++);}

输出为(环境Microsoft Visual Studio Express 2013):i=10


稍作修改

int main(){int i = 10;printf("%d, %d", i++,i);}

其输出为(MVSE2013):10, 11


再作修改

int main(){int i = 10;printf("%d, %d", i, i++);}

其输出结果为(MVSE2013):11, 10


再次修改

int main(){int i = 10;printf("%d, %d", i++, i++);}

其输出结果为(MVSE2013):11, 10

从上面几个例子来看似乎++与其它运算符结合时就开始比较不太好理解,以上看似都是与printf的结合使用时++体现出的特性。其实仔细分析应该与printf无关,而是与参数在传入printf之前是做了神马事情。


int main(){int i = 10;printf("%d, %d", ++i, ++i);}

输出结果为(MVSE2013):12, 12。这个结果说明,在传入参数前进行了两次前缀++。


int main(){int i = 10;printf("%d, %d", ++i, i);}

int main(){int i = 10;printf("%d, %d", i, ++i);}


以上两片程序其输出为(MVSE2013):11, 11。这个结果再次印证了,printf前参数已经做好运算。至少在MVSE2013编译器下是这么实现的。

另外,以上所有程序,在GNU GCC4.8.1及4.8.2编译器测试输出结果与MVSE2013保持高度一致。

void my_memcpy(char *buf, char *str, int len){int i = 0;while(len > i){buf[i++] = str[i];}}int main(){char buf[32];strcpy(buf, "roamboy");my_memcpy(buf,"123", 3);printf(buf);}


其输出结果为(MVSE2013):123mboy,这个结果也是按C语法推测预期的结果,buf与str先从当前i取值运算,直至下次运算i才会被自增。这种推测可以从 buf[i++] = str[i];改为buf[i] = str[i++];时其运行结果一致,得到验证。

然而在GNU GCC 4.8.1及4.8.2版本,其输出结果却大出乎预料,运行结果为:23。从结果可知,程序运行取buf下标时,i的值未被自增,然而取str下标时,i已经是自增过的数值,并且赋值运算符的结合次序也不再是右结合。

综上所有示例,可以得出这样的结论,在这两个编译器中对后缀++的定义没有变,然而后缀++运算与其它运算符一并使用时,一定保证对与其一并使用的其它运算符在所使用的编译器的表现理解足够透彻,这样才可以达到预期效果,不然,很可能产生无法预期错误。

0 0