曾经遇到如下问题:
int a[50]={1,2,3,4,5, 6, 7, 8,9 ,10, 11, 12, 13, 14};
int *p = a;
cout < <(*(++p)++) < <"/t" < <(*p++) < <"/t" < <*p < <"/t" < <endl;
问:输出结果是什么?
答案:3 2 2
研究过程如下:
(1) cout < <(*p++) < <'/t' < <(*p++) < <endl; //2 1
(2) cout < <(*++p) < <'/t' < <(*p++) < <endl; //3 1
(3) cout < <(*++p) < <'/t' < <(*++p) < <endl; //3 2
(4) cout < <(*p++) < <'/t' < <(*++p) < <endl; //2 2
分析1(很多人认可):cout是从右向左处理,从左向右输出
(5)cout < <*(++p)++ < <'/t' < <(*p) < <endl; //2 2
cout < <*p < <endl; //3
分析2(猜想):cout中运算步骤多的先运算,然后再按分析1处理
解释:*(++p)++比*p多一步运算,先算++p,再按分析1处理
验证:下面举例验证
(6)cout < <*(++p)++ < <'/t' < <(*p++) < <endl;//3 2
cout < <*p < <endl;//4
解释:先算++p
(7)cout < <*(++p)++ < <'/t' < <(*(++p)) < <endl; //3 3
解释:先算左边++p,再算右边++p,因此右边输出3
(8)cout < <*(++p)++ < <'/t' < <(*(++p)++) < <endl; //4 3
解释:先算右边和左边的++p,再从右到左运算,因此右边输出3,右边运算完后要移动指针
因此左边输出4
(9)cout < <*(++p)++ < <'/t' < <(*++(++p)) < <endl; //4 4
解释:原因同(8)
(10)cout < <*++(++p) < <'/t' < <(*++(++p)) < <endl; //5 4
解释:原因同上
(11)cout < <*(++(++p))++ < <'/t' < <(*++(++p)) < <endl; //5 5
解释:先算左边++p,再右边++p,再左边++(++p),再右边++(++p),因此右边输出5
(12)cout < <*(++(++p))++ < <'/t' < <*(++(++p))++ < <endl; //6 5
解释:原因同(11)
(13)cout < <*(++(++p)) < <'/t' < <(*++(++p)) < <"/t" < <*p < <endl; //5 4 3
解释:先中间++p,再左边++p,再右边,因此右边输出3,中间再++,输出4,左边再++,输出5
(14)cout < <*(++(++p)) < <'/t' < <(*++(++p)) < <"/t" < <*p++ < <endl; //6 5 3
解释:原因同(13),不同之处右边计算后要移动指针
(15)cout < <*(++(++p))++ < <'/t' < <(*++(++p)) < <"/t" < <*p++ < <endl;//6 6 4
解释:先左边++p,再中间++p,再左边++,再右边运算,因此右边输出4,移动指针后中间++,输出6,
再左边输出6
(16)cout < <(*(++p)++) < <"/t" < <(*p++) < <"/t" < <*p < <"/t" < <endl;
解释:这是研究该问题的起源,目前再分析就比较容易理解
先算左边++p,再右边运算,输出2,再中运算,输出2,移动指针后再左边运算,输出3
总结:(1)我没有搞过编译,分析(2)是猜想,并通过实验验证,结论似乎正确,望高手指正。
(2)很多人谈到,这个问题没有太大实际意义,我想也是。但这是别人问我的一个问题,总得给别人一个解释,
把它当作娱乐吧。