@Purpose
2016-08-16T08:56:43.000000Z
字数 1854
阅读 1106
蛋协
double arr[]={21.1,32.8,23.4,45.2,37.4};double *pt=arr;
A:pt指向的是arr[0]的地址,这时候分别输出pt和*pt的话,pt是地址,*pt是21.1。
pt++;现在pt指向哪里?A:pt现在指向的是arr[1]的地址。输出*pt是32.8
double x=*++pt;x的值是多少?A:pt原先指向arr[1]的地址。此处*与++的优先度相同。优先级相同的话,就从右往左结合,即先++,后*。所以pt先变成了指向arr[2]的地址,后求内容,x为23.4
++*pt;pt指向哪?指向的内容数字是多少?A:pt原先指向arr[2]的地址,此处*与++的优先度相同。优先级相同的话,就从右往左结合,即先*,后++。所以pt先求内容,为23.4 ,后++,为24.4 。由于pt指向的是arr[2]的地址,相当于做了++arr[2]的操作。原来arr[2]的值也会变化。
(*pt)++;pt指向哪?指向的内容数字是多少?A:pt原来指向arr[2]的地址,此处先执行括号内的*,相当于做了arr[2]++的操作。原来的arr[2]的值也会变化,为25.4。
x=*pt++;x的值是多少?*pt的值是多少?A:
这里可以GET到一个语法糖,在此我详细解释一下:
先举个例子:
int i=0;//然后分别续写上三种情况:printf('"%d",++i++); //1=>报错,++需要左值printf("%d",++(i++)); //2=>报错,++需要左值printf("%d",(++i)++); //3=>输出为1
然后在3.的情况下,printf("%d",i); //=>输出为2
可以看出,在3.情况下,++i 和 i++都正确得到了执行。那么1和2呢?
观察1和3,就可以对比出,i++的执行优先级比++i高,那么为什么先执行i++就会报错,而先执行++i就不会报错呢?
我们翻回他们的重载版本做一下对比:
// 前缀形式:int& int::operator++() //这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用{//函数本身无参,意味着是在自身空间内增加1的*this += 1; // 增加return *this; // 取回值}//后缀形式:const int int::operator++(int) //函数返回值是一个非左值型的,与前缀形式的差别所在。{//函数带参,说明有另外的空间开辟int oldValue = *this; // 取回值++(*this); // 增加return oldValue; // 返回被取回的值}
我们做一下对比,就可以发现现象:
1.++i返回的是对象的引用,i++返回的是对象。
2.++i不涉及临时对象的销毁,i++涉及临时对象的销毁。
3.++i的使用需要对象的引用,而不能是对象。
故此,我们可以得出结论:
- 现象1.和3.可知,在
++i++中,由于i++的优先级高,先执行了i++,返回了对象,而++i需要的是对象的引用,故报错,情况1.和2.皆是由于这个原因导致的。- 由于i++需要销毁临时对象,所以在一些数据量偏大的计算中,
++i比i++快那么一点,故编程要尽量养成习惯尽量用++i。
最后,如果仔细阅读这段文字的会发现,我在现象3.中阐述了++i的使用条件,而没有阐述i++的使用条件。其实i++的使用条件需要下面这个两个例子来证明。
int i=0;printf("%d", i++++); // 1printf("%d", ++++i); // 2
例子1. 报错,提示i++需要左值。这就说明了i++的传入也需要对象的引用。
例子2. 正常运行,得到结果:2。
于是,综上我们可以得出结论:
++i的使用需要对象的引用,而不能是对象。
i++的使用需要对象的引用,也不能是对象。
回到问题上,x的值是多少?*pt的值是多少?
有上述分析我们可以知道:
- i++比++i优先度高。
- *和++i的优先度相同。
故此,先运行pt++,后运行*,但是i++返回的是对象(你可以把这理解为+1之前的值),x为arr[2],即25.4。pt指向了arr[3]的地址,45.2。