由C++中的自增、自减运算符引发的思考

来源:互联网 发布:淘宝网禁止好评返现 编辑:程序博客网 时间:2024/06/06 16:53

    今天看到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)看起来更直观,可读性好些。

 

想成为高手还是研究点儿有意义的问题,作为出题者还是出点儿有意义的题,总之还是要做点儿有意义的事儿。

原创粉丝点击