赞
踩
在讨论指针自增问题之前,我们首先要知道*和++ 是同级运算,其运算先后及表达式的最终结果仅受自增特性的影响,所以我们的讨论才有意义。
而对于*、++、和p的组合,可以分为以下5种:
右自增的3种:
*p++ *(p++) (*p)++
左自增的2种:
++*p ++(*p)
按照我最初的设想,构造数组x[3],并用a收集表达式的值,写出代码如下:
#include<stdio.h>
void main() {
int* x[3] = { 1,2,3 };
int* p;
int a=1; //存放表达式的值
p = &x; //使p指向数组x
printf("1 Init=%d p=%d *p=%d\n", a, p, *p);
a = *p++;
printf("2 *p++=%d p=%d *p=%d\n", a, p, *p);
p = &x; //重置指针p
a = *(p++);
printf("3 *(p++)=%d p=%d *p=%d\n", a, p, *p);
p = &x;
a = (*p)++;
printf("4 (*p)++=%d p=%d *p=%d\n", a, p, *p);//!!此处出现问题
p = &x;
a = ++ * p;
printf("5 ++*p=%d p=%d *p=%d\n", a, p, *p); //
p = &x;
a = ++(*p);
printf("6 ++(*p)=%d p=%d *p=%d\n", a, p, *p);
}
运行结果如下:
1 Init=1 p=5241208 *p=1
2 *p++=1 p=5241212 *p=2
3 *p(++)=1 p=5241212 *p=2
4 (*p)++=1 p=5241208 *p=2
5 ++*p=3 p=5241208 *p=3
6 ++(*p)=4 p=5241208 *p=4
通过第1行到第3行的结果,我们可以证明,因为右++需要在表达式整个运行完之后执行,所以表达式本身的值不受右++和()的影响。运行完之后,p增加一个地址单元长度,指向数组下一个数据元素。
但是在第四行,p指向的地址没有改变,但是*p的值发生了变化,这是由于(*p)等价于x[0](数组下标为0,位序是1),所以表达式 (*p)++ 相当于是使数组第一项数据元素自增。
并且这一原因也导致后续的每一次左++都使 *p (a[0])自增1。
所以我们在(*p)++=1 执行后,重置x[0],再次运行如下代码:
void main() {
int* x[3] = { 1,2,3 };
int* p;
int a=1; //存放表达式的值
p = &x;
printf("1 Init=%d p=%d *p=%d\n", a, p, *p);
a = *p++;
printf("2 *p++=%d p=%d *p=%d\n", a, p, *p);
p = &x;
a = *(p++);
printf("3 *(p++)=%d p=%d *p=%d\n", a, p, *p);
p = &x;
a = (*p)++;
printf("4 (*p)++=%d p=%d *p=%d\n", a, p, *p);
x[0] = 1;
p = &x;
a = ++ * p;
printf("5 ++*p=%d p=%d *p=%d\n", a, p, *p);
x[0] = 1;
p = &x;
a = ++(*p);
printf("6 ++(*p)=%d p=%d *p=%d\n", a, p, *p);
}
可以得到如下结果:
1 Init=1 p=9699016 *p=1
2 *p++=1 p=9699020 *p=2
3 *(p++)=1 p=9699020 *p=2
4 (*p)++=1 p=9699016 *p=2
5 ++*p=2 p=9699016 *p=2
6 ++(*p)=2 p=9699016 *p=2
证明我们的猜想。
总结:
*p++ 和 *(p++) 等价 ++*p 和 ++(*p) 等价
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。