由C++中的自增、自减运算符引发的思考
2011-04-17 23:11
281 查看
今天看到CSDN上又有初学C++的朋友问到C++中自增、自减运算符前缀、后缀形式的运算符使用的问题,觉得这个问题很普遍的,应该问到的挺多的,这么多年在考试题、面试题中几乎是个必考的问题,先不去说相关的知识点,我就想看一下关于这个问题讨论的现状,结果发现很多人讨论得还挺“深入”。
比如:
int n=0, m=0;
i= (n++)+(n++)+(n++);
j = (++m)+(++m)+(++m)
k=-i++;
后缀运算:
(1)j=(5,6,(i++)+(i++)+(i++)): j=9(3+3+3)
(2)j=(k++,6,(i++)+(i++)+(i++)): j=9(3+3+3)
(3)j=1?(i++)+(i++)+(i++): 0: j=9(3+3+3)
(4)j=i?(i++)+(i++)+(i++): 0: j=12(3+4+5)
(5)j=k++?(i++)+(i++)+(i++): 0: j=12(3+4+5)
前缀运算:
(6)j=(5,i,(++i)+(++i)+(++i)): j=18(6+6+6)
(7)j=(5,k++,(++i)+(++i)+(++i)): j=15(4+5+6)
(8)j=1?(++i)+(++i)+(++i): 0: j=18(6+6+6)
(9)j=1?(k++,(+i)+(++i)+++i)): 0: j=15(4+5+6)
(10)j=k++?(++i)+(++i)+(++i): 0: j=15(4+5+6)
int b=a++*++a*a++*++a;
printf(“%d, %d, %d”, n++, n ++n);
且不去管这些问题有多难,标准如何定义、编译器如何实现、编译器是否有BUG、编译器对标准的实现程度等等一素列可能影响这些问题的因素,我们挨过来考虑几个问题:
1) 这种表达式有没有实际的应用场景?
2)这种复杂的表达式是否可以简化成其它表达式?
3)这种方式比其它形式的同效果代码有什么优势?
对于第一个问题,我能想到的场景就是考试(包括学校和应聘笔试),除了考试我还真就没有见过实际使用这么复杂表达式的,除非有人想表现一下让人觉得他是高手,但实际上可能聪明反被聪明误。比如i= (n++)+(n++)+(n++),哪里有可能用到呢?即使标准中明确规定了其行为、编译器也是按照标准实现的,但别忘了,编译器也是软件也是人编写出来了,它同样可能存在各种各样的BUG,即使目前的编译器版本没有问题,也不能保证以后哪天编译器升级了,或者换了编译器你的代码还好用。
对于第二个问题,答案是肯定的。自增与自减运算符本身就可以被替换成+与-运算。
那就应该考虑第三个问题了,这什么优势吗?除了上面说的写代码的为了显摆一下自己的“技术”没有什么优势,只能使代码的可读性很差,维护起来更困难,即使代码是正确的,而且不会因为编译器带来不确定的行为,那么读的人是不是也能够一眼看出来代码的意图呢?如果不能,就是说你的代码可读性差了。
至于效率,++与--除了编码效率高一点,少敲几个字符,并不能给运行时带来性能上的提升,其实也不能节约多少编码时间。
所以,在工程上还是不要使用包含++或--的太复杂的表达式,而考试出题出太复杂也是没有什么意义,只要知道j=++i与j=i++执行结果的不同也就足够了,建议出题的老师门也不要再出这种没有意义的考题了,出这样的题与研究这样的题同样没有意义,只是在浪费时间,浪费自己的时间,同时也是浪费应试者的时间。
类似的问题又想到运算符结合顺序的问题,比如对于指针pi,*pi++是(*pi)++还是*(pi++)等,诸如此类问题,研究这种题同样没有意义,在工程上强烈建议还是把括号加上。我是比较懒的,结合顺序我一直记不住,所以我的代码都是带有括号的,比如 a || b && c,还是要写成a || (b && c)看起来更直观,可读性好些。
想成为高手还是研究点儿有意义的问题,作为出题者还是出点儿有意义的题,总之还是要做点儿有意义的事儿。
比如:
int n=0, m=0;
i= (n++)+(n++)+(n++);
j = (++m)+(++m)+(++m)
k=-i++;
后缀运算:
(1)j=(5,6,(i++)+(i++)+(i++)): j=9(3+3+3)
(2)j=(k++,6,(i++)+(i++)+(i++)): j=9(3+3+3)
(3)j=1?(i++)+(i++)+(i++): 0: j=9(3+3+3)
(4)j=i?(i++)+(i++)+(i++): 0: j=12(3+4+5)
(5)j=k++?(i++)+(i++)+(i++): 0: j=12(3+4+5)
前缀运算:
(6)j=(5,i,(++i)+(++i)+(++i)): j=18(6+6+6)
(7)j=(5,k++,(++i)+(++i)+(++i)): j=15(4+5+6)
(8)j=1?(++i)+(++i)+(++i): 0: j=18(6+6+6)
(9)j=1?(k++,(+i)+(++i)+++i)): 0: j=15(4+5+6)
(10)j=k++?(++i)+(++i)+(++i): 0: j=15(4+5+6)
int b=a++*++a*a++*++a;
printf(“%d, %d, %d”, n++, n ++n);
且不去管这些问题有多难,标准如何定义、编译器如何实现、编译器是否有BUG、编译器对标准的实现程度等等一素列可能影响这些问题的因素,我们挨过来考虑几个问题:
1) 这种表达式有没有实际的应用场景?
2)这种复杂的表达式是否可以简化成其它表达式?
3)这种方式比其它形式的同效果代码有什么优势?
对于第一个问题,我能想到的场景就是考试(包括学校和应聘笔试),除了考试我还真就没有见过实际使用这么复杂表达式的,除非有人想表现一下让人觉得他是高手,但实际上可能聪明反被聪明误。比如i= (n++)+(n++)+(n++),哪里有可能用到呢?即使标准中明确规定了其行为、编译器也是按照标准实现的,但别忘了,编译器也是软件也是人编写出来了,它同样可能存在各种各样的BUG,即使目前的编译器版本没有问题,也不能保证以后哪天编译器升级了,或者换了编译器你的代码还好用。
对于第二个问题,答案是肯定的。自增与自减运算符本身就可以被替换成+与-运算。
那就应该考虑第三个问题了,这什么优势吗?除了上面说的写代码的为了显摆一下自己的“技术”没有什么优势,只能使代码的可读性很差,维护起来更困难,即使代码是正确的,而且不会因为编译器带来不确定的行为,那么读的人是不是也能够一眼看出来代码的意图呢?如果不能,就是说你的代码可读性差了。
至于效率,++与--除了编码效率高一点,少敲几个字符,并不能给运行时带来性能上的提升,其实也不能节约多少编码时间。
所以,在工程上还是不要使用包含++或--的太复杂的表达式,而考试出题出太复杂也是没有什么意义,只要知道j=++i与j=i++执行结果的不同也就足够了,建议出题的老师门也不要再出这种没有意义的考题了,出这样的题与研究这样的题同样没有意义,只是在浪费时间,浪费自己的时间,同时也是浪费应试者的时间。
类似的问题又想到运算符结合顺序的问题,比如对于指针pi,*pi++是(*pi)++还是*(pi++)等,诸如此类问题,研究这种题同样没有意义,在工程上强烈建议还是把括号加上。我是比较懒的,结合顺序我一直记不住,所以我的代码都是带有括号的,比如 a || b && c,还是要写成a || (b && c)看起来更直观,可读性好些。
想成为高手还是研究点儿有意义的问题,作为出题者还是出点儿有意义的题,总之还是要做点儿有意义的事儿。
相关文章推荐
- 一个C++程序编译失败引发的思考
- 由Google Log库glog循环打印到一行引发的C++知识点思考
- 一道二级C题引发的思考-- c++函数传递指针的本质 与 字符串指针与字符数组的区别
- 助教:c/c++——数组元素奇偶排列:由此引发对if和while语句的简单问题的思考
- 一个例子引发的思考——C++内存地址
- 改善C++ 程序的150个建议学习之建议2:避免那些由运算符引发的混乱
- C++ 一道简单的题目引发的思考
- 由一个C++问题引发的讨论和思考(未完待续)
- C++中强迫隐式转换this对象到基类所引发的思考
- 由c++循环中局部变量地址不变而引发的思考
- 一个c++题目引发的思考
- 百度的框计算引发的思考----专注
- c++下标运算符的理解和带上机总结一些小技巧
- c++重载箭头运算符
- C++中不能被重载的运算符
- PHP中如何保持SESSION以及由此引发的一些思考
- 【转载】一次面试引发的思考(中小型网站优化思考)
- C++标准转换运算符reinterpret_cast
- required 引发的小小思考
- c++成员运算符重载和友元运算符重载的比较(以++,--运算符为例)